Last active
June 9, 2023 10:36
-
-
Save publu/3707ad4c26eb99cdba104fddb4194c31 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.0; | |
import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | |
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | |
import "@openzeppelin/contracts/access/Ownable2Step.sol"; | |
import "@openzeppelin/contracts/security/Pausable.sol"; | |
/** | |
* @title TokenWrapper | |
* @dev A contract that allows users to wrap and unwrap an ERC20 token. | |
* It provides a bridging functionality with Axelar using POL (Protocol-Owned Liquidity), | |
* and an additional layer of security for users in case of bridge issues. | |
* Users and the protocol can wrap the MAI token into the Axelar ecosystem to bridge | |
* it across various chains available in the Axelar bridge. | |
*/ | |
contract TokenWrapper is ERC20, Ownable2Step, Pausable { | |
IERC20 public constant token = IERC20(0x8D6CeBD76f18E1558D4DB88138e2DeFB3909fAD6); // MAI on ETH | |
event Deposit(address indexed dst, uint256 wad); | |
event Withdrawal(address indexed src, uint256 wad); | |
/** | |
* @dev Initializes the TokenWrapper contract. | |
*/ | |
constructor() ERC20("Wrapped MAI", "WMAI") {} | |
/** | |
* @dev Allows users to deposit tokens into the contract and receive wrapped tokens in return. | |
* @param amount The amount of tokens to deposit. | |
*/ | |
function deposit(uint256 amount) public whenNotPaused { | |
// Transfers tokens from the user to the contract | |
bool transferSuccessful = token.transferFrom(_msgSender(), address(this), amount); | |
require(transferSuccessful, "Token transfer was not successful."); | |
_mint(_msgSender(), amount); // Mints wrapped tokens to the user | |
emit Deposit(_msgSender(), amount); // Emits the Deposit event | |
} | |
/** | |
* @dev Allows users to withdraw wrapped tokens and receive the underlying tokens in return. | |
* @param amount The amount of wrapped tokens to withdraw. | |
*/ | |
function withdraw(uint256 amount) public whenNotPaused { | |
_burn(_msgSender(), amount); // Burns the wrapped tokens from the user | |
// Transfers the underlying tokens to the user | |
bool transferSuccessful = token.transfer(_msgSender(), amount); | |
require(transferSuccessful, "Token transfer was not successful."); | |
emit Withdrawal(_msgSender(), amount); // Emits the Withdrawal event | |
} | |
/** | |
* @dev Allows the owner of the contract to pause token transfers. | |
* Only the contract owner can call this function. | |
*/ | |
function pause() public onlyOwner { | |
_pause(); // Pauses token transfers | |
} | |
/** | |
* @dev Allows the owner of the contract to unpause token transfers. | |
* Only the contract owner can call this function. | |
*/ | |
function unpause() public onlyOwner { | |
_unpause(); // Unpauses token transfers | |
} | |
/** | |
* @dev Allows the owner to withdraw any ERC20 tokens sent here accidentally. | |
* @param _tokenAddress The address of the token to withdraw. | |
* @param _amount The amount of the token to withdraw. | |
*/ | |
function withdrawLostTokens(address _tokenAddress, uint256 _amount) public onlyOwner { | |
IERC20 _token = IERC20(_tokenAddress); | |
require(_token != token, "Cannot withdraw the wrapped token"); | |
require(_token.balanceOf(address(this)) >= _amount, "Not enough balance"); | |
_token.transfer(_msgSender(), _amount); | |
} | |
/** | |
* @dev Allows the owner to withdraw any extra balance of the underlying token. | |
*/ | |
function withdrawExtraBalance() public onlyOwner { | |
uint256 extraBalance = token.balanceOf(address(this)) - totalSupply(); | |
require(extraBalance > 0, "No extra balance to withdraw"); | |
token.transfer(_msgSender(), extraBalance); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment