-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #39 from axieinfinity/merge/release/v0.1.0-feature…
…/math chore(`math`): merge from `release/v0.1.0`
- Loading branch information
Showing
6 changed files
with
279 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
interface IWRON { | ||
/** | ||
* @dev Deposit RON and increase balance WRON tokens of sender. | ||
*/ | ||
function deposit() external payable; | ||
|
||
/// @dev See {IERC20-transfer}. | ||
function transfer(address to, uint256 value) external returns (bool); | ||
|
||
/// @dev See {IERC20-transferFrom}. | ||
function transferFrom(address src, address dst, uint256 wad) external returns (bool); | ||
|
||
/** | ||
* @dev Withdraw RON and decrease balance WRON tokens of sender. | ||
*/ | ||
function withdraw(uint256) external; | ||
|
||
/// @dev See {IERC20-balanceOf}. | ||
function balanceOf(address) external view returns (uint256); | ||
|
||
/// @dev See {IERC20-approve}. | ||
function approve(address guy, uint256 wad) external returns (bool); | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
interface IWRONHelper { | ||
/** | ||
* @dev Returns WRON address. | ||
*/ | ||
function WRON() external view returns (address); | ||
|
||
/** | ||
* @dev Deposit WRON and withdraw RON token. | ||
* | ||
* Requirements: | ||
* - This contract must be approved `amount` WRON tokens by sender. | ||
*/ | ||
function withdraw(uint256 amount) external; | ||
|
||
/** | ||
* @dev Deposit WRON and withdraw RON token to address `to`. | ||
* | ||
* Requirements: | ||
* - This contract must be approved `amount` WRON tokens by sender. | ||
*/ | ||
function withdrawTo(address payable to, uint256 amount) external; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import { Strings } from "../../../lib/openzeppelin-contracts/contracts/utils/Strings.sol"; | ||
|
||
/** | ||
* @title RONTransferHelper | ||
*/ | ||
library RONTransferHelper { | ||
/** | ||
* @dev Transfers RON and wraps result for the method caller to a recipient. | ||
*/ | ||
function safeTransfer(address payable to, uint256 value) internal { | ||
bool success = send(to, value); | ||
|
||
if (!success) { | ||
revert( | ||
string.concat( | ||
"TransferHelper: could not transfer RON to ", | ||
Strings.toHexString(uint160(address(to)), 20), | ||
" value ", | ||
Strings.toHexString(value) | ||
) | ||
); | ||
} | ||
} | ||
|
||
/** | ||
* @dev Returns whether the call was success. | ||
* Note: this function should use with the `ReentrancyGuard`. | ||
*/ | ||
function send(address payable to, uint256 value) internal returns (bool success) { | ||
(success,) = to.call{ value: value }(new bytes(0)); | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import { IWRON } from "../../interfaces/IWRON.sol"; | ||
import { IWRONHelper } from "../../interfaces/IWRONHelper.sol"; | ||
import { RONTransferHelper } from "./RONTransferHelper.sol"; | ||
import { TransferFromHelper } from "./TransferFromHelper.sol"; | ||
import { TransferHelper } from "./TransferHelper.sol"; | ||
|
||
library RONTransferHelperExtended { | ||
/** | ||
* @dev Safely unwraps tokens if it is WRON token and transfers them to a specified recipient. | ||
* @param wron Address of the WRON contract. | ||
* @param token Address of the ERC20 token to unwrap and transfer. | ||
* @param to Address of the recipient to transfer the tokens to. | ||
* @param amount Amount of tokens to transfer. | ||
* | ||
* Note: This function may cause a revert if the consumer contract is a proxy, consider using the method | ||
* `safeUnwrapTokenAndTransferWithHelper` instead. | ||
*/ | ||
function safeUnwrapTokenAndTransfer(IWRON wron, address token, address payable to, uint256 amount) internal { | ||
if (token == address(wron)) { | ||
// Check whether the recipient receives RON | ||
if (RONTransferHelper.send(to, 0)) { | ||
wron.withdraw(amount); | ||
RONTransferHelper.safeTransfer(to, amount); | ||
return; | ||
} | ||
} | ||
|
||
TransferHelper.safeTransfer(token, to, amount); | ||
} | ||
|
||
/** | ||
* @dev See `safeUnwrapTokenAndTransfer`. | ||
* | ||
* Requirements: | ||
* - The consumer contract must approve the contract `wronHelper`. | ||
* | ||
* Note: This function supports the use of a proxy contract by using the WRONHelper contract to unwrap WRON and | ||
* transfer RON. | ||
*/ | ||
function safeUnwrapTokenAndTransferWithHelper( | ||
IWRON wron, | ||
IWRONHelper wronHelper, | ||
address token, | ||
address payable to, | ||
uint256 amount | ||
) internal { | ||
if (token == address(wron)) { | ||
// Check whether the recipient receives RON | ||
if (RONTransferHelper.send(to, 0)) { | ||
wron.approve(address(wronHelper), amount); | ||
wronHelper.withdrawTo(to, amount); | ||
return; | ||
} | ||
} | ||
|
||
TransferHelper.safeTransfer(token, to, amount); | ||
} | ||
|
||
/** | ||
* @dev Safely unwraps tokens if it is WRON token from specified sender, and transfers them to a specified recipient. | ||
* @param wron Address of the WRON contract. | ||
* @param token Address of the ERC20 token to unwrap and transfer. | ||
* @param from Address of the sender on whose behalf the tokens will be unwrapped and transferred. | ||
* @param to Address of the recipient to transfer the tokens to. | ||
* @param amount Amount of tokens to transfer. | ||
* | ||
* Note: This function may cause a revert if the consumer contract is a proxy, consider using the method | ||
* `safeUnwrapTokenAndTransferFromWithHelper` instead. | ||
*/ | ||
function safeUnwrapTokenAndTransferFrom(IWRON wron, address token, address from, address payable to, uint256 amount) | ||
internal | ||
{ | ||
if (token == address(wron)) { | ||
// Check whether the recipient receives RON | ||
if (RONTransferHelper.send(to, 0)) { | ||
TransferFromHelper.safeTransferFrom(token, from, address(this), amount); | ||
IWRON(wron).withdraw(amount); | ||
RONTransferHelper.safeTransfer(to, amount); | ||
return; | ||
} | ||
} | ||
|
||
TransferFromHelper.safeTransferFrom(token, from, to, amount); | ||
} | ||
|
||
/** | ||
* @dev See `safeUnwrapTokenAndTransfer`. | ||
* | ||
* Requirements: | ||
* - The consumer contract must approve the contract `wronHelper`. | ||
* | ||
* Note: This function supports the use of a proxy contract by using the WRONHelper contract to unwrap WRON and | ||
* transfer RON. | ||
*/ | ||
function safeUnwrapTokenAndTransferFromWithHelper( | ||
IWRON wron, | ||
IWRONHelper wronHelper, | ||
address token, | ||
address from, | ||
address payable to, | ||
uint256 amount | ||
) internal { | ||
if (token == address(wron)) { | ||
// Check whether the recipient receives RON | ||
if (RONTransferHelper.send(to, 0)) { | ||
TransferFromHelper.safeTransferFrom(token, from, address(this), amount); | ||
wron.approve(address(wronHelper), amount); | ||
wronHelper.withdrawTo(to, amount); | ||
return; | ||
} | ||
} | ||
|
||
TransferFromHelper.safeTransferFrom(token, from, to, amount); | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import { Strings } from "../../../lib/openzeppelin-contracts/contracts/utils/Strings.sol"; | ||
|
||
/** | ||
* @title TransferFromHelper | ||
* @dev Wraps transfer from methods for ERC20 tokens that do not consistently return true/false or revert. | ||
*/ | ||
library TransferFromHelper { | ||
/** | ||
* @dev Transfers token and wraps result for the input address to a recipient. | ||
*/ | ||
function safeTransferFrom(address token, address from, address to, uint256 value) internal { | ||
(bool success, bytes memory data) = token.call( | ||
abi.encodeWithSelector( | ||
0x23b872dd, // IERC20.transferFrom.selector | ||
from, | ||
to, | ||
value | ||
) | ||
); | ||
|
||
if (!success || !(data.length == 0 || abi.decode(data, (bool)))) { | ||
revert( | ||
string.concat( | ||
"TransferFromHelper: could not transfer token ", | ||
Strings.toHexString(uint160(token), 20), | ||
" from ", | ||
Strings.toHexString(uint160(from), 20), | ||
" to ", | ||
Strings.toHexString(uint160(to), 20), | ||
" value ", | ||
Strings.toHexString(value) | ||
) | ||
); | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import { Strings } from "../../../lib/openzeppelin-contracts/contracts/utils/Strings.sol"; | ||
|
||
/** | ||
* @title TransferHelper | ||
* @dev Wraps transfer methods for ERC20/native tokens that do not consistently return true/false or revert. | ||
*/ | ||
library TransferHelper { | ||
/** | ||
* @dev Transfers token and wraps result for the method caller to a recipient. | ||
*/ | ||
function safeTransfer(address token, address to, uint256 value) internal { | ||
(bool success, bytes memory data) = token.call( | ||
abi.encodeWithSelector( | ||
0xa9059cbb, // IERC20.transfer.selector | ||
to, | ||
value | ||
) | ||
); | ||
|
||
if (!success || !(data.length == 0 || abi.decode(data, (bool)))) { | ||
revert( | ||
string.concat( | ||
"TransferHelper: could not transfer token ", | ||
Strings.toHexString(uint160(token), 20), | ||
" to ", | ||
Strings.toHexString(uint160(to), 20), | ||
" value ", | ||
Strings.toHexString(value) | ||
) | ||
); | ||
} | ||
} | ||
} |