Latest 25 from a total of 73 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Transfer | 24636936 | 98 days ago | IN | 0.001 ETH | 0.00000214 | ||||
| Withdraw | 22998719 | 139 days ago | IN | 0 ETH | 0.0000019 | ||||
| Transfer | 21861699 | 166 days ago | IN | 0 ETH | 0.00000152 | ||||
| Transfer And Dep... | 18728519 | 262 days ago | IN | 0 ETH | 0.00001005 | ||||
| Transfer And Dep... | 18728447 | 262 days ago | IN | 0 ETH | 0.00001007 | ||||
| Transfer And Dep... | 18728395 | 262 days ago | IN | 0 ETH | 0.00001008 | ||||
| Transfer And Dep... | 18728304 | 262 days ago | IN | 0 ETH | 0.00001005 | ||||
| Transfer And Dep... | 18728245 | 262 days ago | IN | 0 ETH | 0.00001209 | ||||
| Transfer And Dep... | 18728102 | 262 days ago | IN | 0 ETH | 0.00000698 | ||||
| Transfer And Dep... | 18727717 | 262 days ago | IN | 0 ETH | 0.00001245 | ||||
| Transfer And Dep... | 18727633 | 262 days ago | IN | 0 ETH | 0.00000693 | ||||
| Swap | 18656659 | 265 days ago | IN | 0 ETH | 0.00000198 | ||||
| Withdraw | 3026572 | 674 days ago | IN | 0 ETH | 0.0000588 | ||||
| Withdraw | 3026526 | 674 days ago | IN | 0 ETH | 0.00005845 | ||||
| Withdraw | 3026515 | 674 days ago | IN | 0 ETH | 0.00008523 | ||||
| Transfer | 1637729 | 742 days ago | IN | 0.0000001 ETH | 0.00008141 | ||||
| Transfer | 1637701 | 742 days ago | IN | 0.0000001 ETH | 0.00008121 | ||||
| Transfer | 1637674 | 742 days ago | IN | 0.0000001 ETH | 0.00008273 | ||||
| Transfer | 1637647 | 742 days ago | IN | 0.0000001 ETH | 0.00008236 | ||||
| Transfer | 1637622 | 742 days ago | IN | 0.0000001 ETH | 0.00008199 | ||||
| Transfer | 1637595 | 742 days ago | IN | 0.0000001 ETH | 0.00008169 | ||||
| Transfer | 1637570 | 742 days ago | IN | 0.0000001 ETH | 0.00008127 | ||||
| Transfer | 1637546 | 742 days ago | IN | 0.0000001 ETH | 0.00007926 | ||||
| Transfer | 1637489 | 742 days ago | IN | 0.0000001 ETH | 0.0000784 | ||||
| Transfer | 1637458 | 742 days ago | IN | 0.0000001 ETH | 0.00007806 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 28258499 | 4 mins ago | 0 ETH | ||||
| 28258499 | 4 mins ago | 0 ETH | ||||
| 28258499 | 4 mins ago | 0 ETH | ||||
| 28258499 | 4 mins ago | 0 ETH | ||||
| 28258499 | 4 mins ago | 0.00177746 ETH | ||||
| 28258499 | 4 mins ago | 0 ETH | ||||
| 28258499 | 4 mins ago | 0 ETH | ||||
| 28258499 | 4 mins ago | 0 ETH | ||||
| 28257724 | 32 mins ago | 0 ETH | ||||
| 28257724 | 32 mins ago | 0 ETH | ||||
| 28257724 | 32 mins ago | 0 ETH | ||||
| 28257724 | 32 mins ago | 0 ETH | ||||
| 28257724 | 32 mins ago | 0 ETH | ||||
| 28257724 | 32 mins ago | 0 ETH | ||||
| 28257485 | 41 mins ago | 0 ETH | ||||
| 28257485 | 41 mins ago | 0.01465401 ETH | ||||
| 28257485 | 41 mins ago | 0 ETH | ||||
| 28257485 | 41 mins ago | 0 ETH | ||||
| 28257485 | 41 mins ago | 0 ETH | ||||
| 28257485 | 41 mins ago | 0 ETH | ||||
| 28257485 | 41 mins ago | 0 ETH | ||||
| 28257187 | 52 mins ago | 0 ETH | ||||
| 28257187 | 52 mins ago | 0.00011462 ETH | ||||
| 28257187 | 52 mins ago | 0 ETH | ||||
| 28257187 | 52 mins ago | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
SyncSwapVault
Compiler Version
v0.8.15+commit.e14f2714
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.0;
import "../interfaces/IWETH.sol";
import "../interfaces/token/IERC20.sol";
import "../libraries/ReentrancyGuard.sol";
import "../libraries/TransferHelper.sol";
import "./VaultFlashLoans.sol";
/// @notice The vault stores all tokens supporting internal transfers to save gas.
contract SyncSwapVault is VaultFlashLoans {
address private constant NATIVE_ETH = address(0);
address public immutable override wETH;
mapping(address => mapping(address => uint)) private balances; // token -> account -> balance
mapping(address => uint) public override reserves; // token -> reserve
constructor(address _wETH) VaultFlashLoans(msg.sender) {
wETH = _wETH;
}
receive() external payable {
// Deposit ETH via fallback if not from the wETH withdraw.
if (msg.sender != wETH) {
deposit(NATIVE_ETH, msg.sender);
}
}
function balanceOf(address token, address account) external view override returns (uint balance) {
// Ensure the same `balances` as native ETH.
if (token == wETH) {
token = NATIVE_ETH;
}
return balances[token][account];
}
// Deposit
function deposit(address token, address to) public payable override nonReentrant returns (uint amount) {
if (token == NATIVE_ETH) {
// Use `msg.value` as amount for native ETH.
amount = msg.value;
} else {
require(msg.value == 0);
if (token == wETH) {
// Ensure the same `reserves` and `balances` as native ETH.
token = NATIVE_ETH;
// Use balance as amount for wETH.
amount = IERC20(wETH).balanceOf(address(this));
// Unwrap wETH to native ETH.
IWETH(wETH).withdraw(amount);
} else {
// Derive real amount with balance and reserve for ERC20 tokens.
amount = IERC20(token).balanceOf(address(this)) - reserves[token];
}
}
// Increase token reserve.
reserves[token] += amount;
// Increase token balance for recipient.
unchecked {
/// `balances` cannot overflow if `reserves` doesn't overflow.
balances[token][to] += amount;
}
}
function depositETH(address to) external payable override nonReentrant returns (uint amount) {
// Use `msg.value` as amount for native ETH.
amount = msg.value;
// Increase token reserve.
reserves[NATIVE_ETH] += amount;
// Increase token balance for recipient.
unchecked {
/// `balances` cannot overflow if `reserves` doesn't overflow.
balances[NATIVE_ETH][to] += amount;
}
}
// Transfer tokens from sender and deposit, requires approval.
function transferAndDeposit(address token, address to, uint amount) external payable override nonReentrant returns (uint) {
if (token == NATIVE_ETH) {
require(amount == msg.value);
} else {
require(msg.value == 0);
if (token == wETH) {
// Ensure the same `reserves` and `balances` as native ETH.
token = NATIVE_ETH;
// Receive wETH from sender.
IWETH(wETH).transferFrom(msg.sender, address(this), amount);
// Unwrap wETH to native ETH.
IWETH(wETH).withdraw(amount);
} else {
// Receive ERC20 tokens from sender.
TransferHelper.safeTransferFrom(token, msg.sender, address(this), amount);
// Derive real amount with balance and reserve for ERC20 tokens.
amount = IERC20(token).balanceOf(address(this)) - reserves[token];
}
}
// Increase token reserve.
reserves[token] += amount;
// Increase token balance for recipient.
unchecked {
/// `balances` cannot overflow if `reserves` doesn't overflow.
balances[token][to] += amount;
}
return amount;
}
// Transfer
function transfer(address token, address to, uint amount) external override nonReentrant {
// Ensure the same `reserves` and `balances` as native ETH.
if (token == wETH) {
token = NATIVE_ETH;
}
// Decrease token balance for sender.
balances[token][msg.sender] -= amount;
// Increase token balance for recipient.
unchecked {
/// `balances` cannot overflow if `balances` doesn't underflow.
balances[token][to] += amount;
}
}
// Withdraw
function _wrapAndTransferWETH(address to, uint amount) private {
// Wrap native ETH to wETH.
IWETH(wETH).deposit{value: amount}();
// Send wETH to recipient.
IWETH(wETH).transfer(to, amount);
}
function withdraw(address token, address to, uint amount) external override nonReentrant {
if (token == NATIVE_ETH) {
// Send native ETH to recipient.
TransferHelper.safeTransferETH(to, amount);
} else {
if (token == wETH) {
// Ensure the same `reserves` and `balances` as native ETH.
token = NATIVE_ETH;
_wrapAndTransferWETH(to, amount);
} else {
// Send ERC20 tokens to recipient.
TransferHelper.safeTransfer(token, to, amount);
}
}
// Decrease token balance for sender.
balances[token][msg.sender] -= amount;
// Decrease token reserve.
unchecked {
/// `reserves` cannot underflow if `balances` doesn't underflow.
reserves[token] -= amount;
}
}
// Withdraw with mode.
// 0 = DEFAULT
// 1 = UNWRAPPED
// 2 = WRAPPED
function withdrawAlternative(address token, address to, uint amount, uint8 mode) external override nonReentrant {
if (token == NATIVE_ETH) {
if (mode == 2) {
_wrapAndTransferWETH(to, amount);
} else {
// Send native ETH to recipient.
TransferHelper.safeTransferETH(to, amount);
}
} else {
if (token == wETH) {
// Ensure the same `reserves` and `balances` as native ETH.
token = NATIVE_ETH;
if (mode == 1) {
// Send native ETH to recipient.
TransferHelper.safeTransferETH(to, amount);
} else {
_wrapAndTransferWETH(to, amount);
}
} else {
// Send ERC20 tokens to recipient.
TransferHelper.safeTransfer(token, to, amount);
}
}
// Decrease token balance for sender.
balances[token][msg.sender] -= amount;
// Decrease token reserve.
unchecked {
/// `reserves` cannot underflow if `balances` doesn't underflow.
reserves[token] -= amount;
}
}
function withdrawETH(address to, uint amount) external override nonReentrant {
// Send native ETH to recipient.
TransferHelper.safeTransferETH(to, amount);
// Decrease token balance for sender.
balances[NATIVE_ETH][msg.sender] -= amount;
// Decrease token reserve.
unchecked {
/// `reserves` cannot underflow if `balances` doesn't underflow.
reserves[NATIVE_ETH] -= amount;
}
}
}// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity >=0.5.0;
interface IWETH {
function deposit() external payable;
function transfer(address to, uint value) external returns (bool);
function transferFrom(address from, address to, uint value) external returns (bool);
function withdraw(uint) external;
}// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity >=0.5.0;
interface IFeeRecipient {
/// @dev Notifies the fee recipient after sent fees.
function notifyFees(
uint16 feeType,
address token,
uint amount,
uint feeRate,
bytes calldata data
) external;
}// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity >=0.5.0;
import "./IERC20Base.sol";
interface IERC20 is IERC20Base {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity >=0.5.0;
interface IERC20Base {
function totalSupply() external view returns (uint);
function balanceOf(address owner) external view returns (uint);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint amount) external returns (bool);
function transfer(address to, uint amount) external returns (bool);
function transferFrom(address from, address to, uint amount) external returns (bool);
event Approval(address indexed owner, address indexed spender, uint amount);
event Transfer(address indexed from, address indexed to, uint amount);
}// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity >=0.5.0;
interface IERC3156FlashBorrower {
/**
* @dev Receive a flash loan.
* @param initiator The initiator of the loan.
* @param token The loan currency.
* @param amount The amount of tokens lent.
* @param fee The additional amount of tokens to repay.
* @param data Arbitrary data structure, intended to contain user-defined parameters.
* @return The keccak256 hash of "ERC3156FlashBorrower.onFlashLoan"
*/
function onFlashLoan(
address initiator,
address token,
uint256 amount,
uint256 fee,
bytes calldata data
) external returns (bytes32);
}// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity >=0.5.0;
import "./IERC3156FlashBorrower.sol";
interface IERC3156FlashLender {
/**
* @dev The amount of currency available to be lent.
* @param token The loan currency.
* @return The amount of `token` that can be borrowed.
*/
function maxFlashLoan(
address token
) external view returns (uint256);
/**
* @dev The fee to be charged for a given loan.
* @param token The loan currency.
* @param amount The amount of tokens lent.
* @return The amount of `token` to be charged for the loan, on top of the returned principal.
*/
function flashFee(
address token,
uint256 amount
) external view returns (uint256);
/**
* @dev Initiate a flash loan.
* @param receiver The receiver of the tokens in the loan, and the receiver of the callback.
* @param token The loan currency.
* @param amount The amount of tokens lent.
* @param data Arbitrary data structure, intended to contain user-defined parameters.
*/
function flashLoan(
IERC3156FlashBorrower receiver,
address token,
uint256 amount,
bytes calldata data
) external returns (bool);
}// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity >=0.5.0;
import "./IFlashLoanRecipient.sol";
import "./IERC3156FlashLender.sol";
interface IFlashLoan is IERC3156FlashLender {
function flashLoanFeePercentage() external view returns (uint);
/**
* @dev Performs a 'flash loan', sending tokens to `recipient`, executing the `receiveFlashLoan` hook on it,
* and then reverting unless the tokens plus a proportional protocol fee have been returned.
*
* The `tokens` and `amounts` arrays must have the same length, and each entry in these indicates the loan amount
* for each token contract. `tokens` must be sorted in ascending order.
*
* The 'userData' field is ignored by the Vault, and forwarded as-is to `recipient` as part of the
* `receiveFlashLoan` call.
*
* Emits `FlashLoan` events.
*/
function flashLoanMultiple(
IFlashLoanRecipient recipient,
address[] memory tokens,
uint[] memory amounts,
bytes memory userData
) external;
/**
* @dev Emitted for each individual flash loan performed by `flashLoan`.
*/
event FlashLoan(address indexed recipient, address indexed token, uint amount, uint feeAmount);
}// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.7.0 <0.9.0;
// Inspired by Aave Protocol's IFlashLoanReceiver.
interface IFlashLoanRecipient {
/**
* @dev When `flashLoan` is called on the Vault, it invokes the `receiveFlashLoan` hook on the recipient.
*
* At the time of the call, the Vault will have transferred `amounts` for `tokens` to the recipient. Before this
* call returns, the recipient must have transferred `amounts` plus `feeAmounts` for each token back to the
* Vault, or else the entire flash loan will revert.
*
* `userData` is the same value passed in the `IVault.flashLoan` call.
*/
function receiveFlashLoan(
address[] memory tokens,
uint[] memory amounts,
uint[] memory feeAmounts,
bytes memory userData
) external;
}// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity >=0.5.0;
import "./IFlashLoan.sol";
interface IVault is IFlashLoan {
function wETH() external view returns (address);
function reserves(address token) external view returns (uint reserve);
function balanceOf(address token, address owner) external view returns (uint balance);
function deposit(address token, address to) external payable returns (uint amount);
function depositETH(address to) external payable returns (uint amount);
function transferAndDeposit(address token, address to, uint amount) external payable returns (uint);
function transfer(address token, address to, uint amount) external;
function withdraw(address token, address to, uint amount) external;
function withdrawAlternative(address token, address to, uint amount, uint8 mode) external;
function withdrawETH(address to, uint amount) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(msg.sender);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == msg.sender, "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)
pragma solidity ^0.8.0;
import "./Ownable.sol";
abstract contract Pausable is Ownable {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
function setPaused(bool _status) external onlyOwner {
if (_status) {
_requireNotPaused();
emit Paused(msg.sender);
} else {
_requirePaused();
emit Unpaused(msg.sender);
}
_paused = _status;
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(msg.sender);
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(msg.sender);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be _NOT_ENTERED
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
}// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.0;
/// @dev The ETH transfer has failed.
error ETHTransferFailed();
/// @dev The ERC20 `transferFrom` has failed.
error TransferFromFailed();
/// @dev The ERC20 `transfer` has failed.
error TransferFailed();
/// @dev The ERC20 `approve` has failed.
error ApproveFailed();
/// @dev Helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true / false.
library TransferHelper {
function safeApprove(
address token,
address to,
uint value
) internal {
// bytes4(keccak256(bytes("approve(address,uint256)")));
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
if (!success || (data.length != 0 && !abi.decode(data, (bool)))) {
revert ApproveFailed();
}
}
function safeTransfer(
address token,
address to,
uint value
) internal {
// bytes4(keccak256(bytes("transfer(address,uint256)")));
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
if (!success || (data.length != 0 && !abi.decode(data, (bool)))) {
revert TransferFailed();
}
}
function safeTransferFrom(
address token,
address from,
address to,
uint value
) internal {
// bytes4(keccak256(bytes("transferFrom(address,address,uint256)")));
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
if (!success || (data.length != 0 && !abi.decode(data, (bool)))) {
revert TransferFromFailed();
}
}
function safeTransferETH(address to, uint value) internal {
// solhint-disable-next-line avoid-low-level-calls
(bool success, ) = to.call{value: value}("");
if (!success) {
revert ETHTransferFailed();
}
}
}// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;
import "../interfaces/token/IERC20.sol";
import "../interfaces/master/IFeeRecipient.sol";
import "../interfaces/vault/IVault.sol";
import "../interfaces/vault/IFlashLoanRecipient.sol";
import "../libraries/Pausable.sol";
import "../libraries/ReentrancyGuard.sol";
import "../libraries/TransferHelper.sol";
/**
* @dev Handles Flash Loans through the Vault. Calls the `receiveFlashLoan` hook on the flash loan recipient
* contract, which implements the `IFlashLoanRecipient` interface.
*/
abstract contract VaultFlashLoans is IVault, ReentrancyGuard, Pausable {
bytes32 public constant ERC3156_CALLBACK_SUCCESS = keccak256("ERC3156FlashBorrower.onFlashLoan");
/// @dev Absolute maximum fee percentages (1e18 = 100%, 1e16 = 1%).
uint private constant _MAX_PROTOCOL_FLASH_LOAN_FEE_PERCENTAGE = 10e16; // 10%
// All fee percentages are 18-decimal fixed point numbers.
// The flash loan fee is charged whenever a flash loan occurs, as a percentage of the tokens lent.
uint public override flashLoanFeePercentage = 5e14; // 0.05%
address public flashLoanFeeRecipient;
// Events
event FlashLoanFeePercentageChanged(uint oldFlashLoanFeePercentage, uint newFlashLoanFeePercentage);
constructor(address _flashLoanFeeRecipient) {
require(
_flashLoanFeeRecipient != address(0),
"INVALID_FLASH_LOAN_FEE_RECIPIENT"
);
flashLoanFeeRecipient = _flashLoanFeeRecipient;
}
function setFlashLoanFeeRecipient(address _flashLoanFeeRecipient) external onlyOwner {
require(
_flashLoanFeeRecipient != address(0),
"INVALID_FLASH_LOAN_FEE_RECIPIENT"
);
flashLoanFeeRecipient = _flashLoanFeeRecipient;
}
function setFlashLoanFeePercentage(uint newFlashLoanFeePercentage) external onlyOwner {
require(
newFlashLoanFeePercentage <= _MAX_PROTOCOL_FLASH_LOAN_FEE_PERCENTAGE,
"FLASH_LOAN_FEE_PERCENTAGE_TOO_HIGH"
);
emit FlashLoanFeePercentageChanged(flashLoanFeePercentage, newFlashLoanFeePercentage);
flashLoanFeePercentage = newFlashLoanFeePercentage;
}
/**
* @dev Returns the protocol fee amount to charge for a flash loan of `amount`.
*/
function _calculateFlashLoanFeeAmount(uint amount) internal view returns (uint) {
return amount * flashLoanFeePercentage / 1e18;
}
function _payFeeAmount(address token, uint amount) internal {
if (amount != 0) {
address _flashLoanFeeRecipient = flashLoanFeeRecipient;
TransferHelper.safeTransfer(token, _flashLoanFeeRecipient, amount);
IFeeRecipient(_flashLoanFeeRecipient).notifyFees(10, token, amount, flashLoanFeePercentage, "");
}
}
/**
* @dev Performs a 'flash loan', sending tokens to `recipient`, executing the `receiveFlashLoan` hook on it,
* and then reverting unless the tokens plus a proportional protocol fee have been returned.
*
* The `tokens` and `amounts` arrays must have the same length, and each entry in these indicates the loan amount
* for each token contract. `tokens` must be sorted in ascending order.
*
* The 'userData' field is ignored by the Vault, and forwarded as-is to `recipient` as part of the
* `receiveFlashLoan` call.
*
* Emits `FlashLoan` events.
*/
function flashLoanMultiple(
IFlashLoanRecipient recipient,
address[] memory tokens,
uint[] memory amounts,
bytes memory userData
) external override nonReentrant whenNotPaused {
uint tokensLength = tokens.length;
require(tokensLength == amounts.length, "INPUT_LENGTH_MISMATCH");
uint[] memory feeAmounts = new uint[](tokensLength);
uint[] memory preLoanBalances = new uint[](tokensLength);
// Used to ensure `tokens` is sorted in ascending order, which ensures token uniqueness.
address previousToken;
uint i;
address token;
uint amount;
for (; i < tokensLength; ) {
token = tokens[i];
amount = amounts[i];
require(token > previousToken, token == address(0) ? "ZERO_TOKEN" : "UNSORTED_TOKENS");
previousToken = token;
preLoanBalances[i] = IERC20(token).balanceOf(address(this));
feeAmounts[i] = _calculateFlashLoanFeeAmount(amount);
require(preLoanBalances[i] >= amount, "INSUFFICIENT_FLASH_LOAN_BALANCE");
TransferHelper.safeTransfer(token, address(recipient), amount);
unchecked {
++i;
}
}
recipient.receiveFlashLoan(tokens, amounts, feeAmounts, userData);
uint preLoanBalance;
uint postLoanBalance;
uint receivedFeeAmount;
for (i = 0; i < tokensLength; ) {
token = tokens[i];
preLoanBalance = preLoanBalances[i];
// Checking for loan repayment first (without accounting for fees) makes for simpler debugging, and results
// in more accurate revert reasons if the flash loan protocol fee percentage is zero.
postLoanBalance = IERC20(token).balanceOf(address(this));
require(postLoanBalance >= preLoanBalance, "INVALID_POST_LOAN_BALANCE");
// No need for checked arithmetic since we know the loan was fully repaid.
receivedFeeAmount = postLoanBalance - preLoanBalance;
require(receivedFeeAmount >= feeAmounts[i], "INSUFFICIENT_FLASH_LOAN_FEE_AMOUNT");
_payFeeAmount(token, receivedFeeAmount);
emit FlashLoan(address(recipient), token, amounts[i], receivedFeeAmount);
unchecked {
++i;
}
}
}
// EIP-3156 Implementations
/**
* @dev The amount of currency available to be lent.
* @param token The loan currency.
* @return The amount of `token` that can be borrowed.
*/
function maxFlashLoan(address token) external view override returns (uint256) {
return IERC20(token).balanceOf(address(this));
}
/**
* @dev The fee to be charged for a given loan.
* @param amount The amount of tokens lent.
* @return The amount of `token` to be charged for the loan, on top of the returned principal.
*/
function flashFee(address /*token*/, uint256 amount) external view override returns (uint256) {
return _calculateFlashLoanFeeAmount(amount);
}
/**
* @dev Initiate a flash loan.
* @param receiver The receiver of the tokens in the loan, and the receiver of the callback.
* @param token The loan currency.
* @param amount The amount of tokens lent.
* @param userData Arbitrary data structure, intended to contain user-defined parameters.
*/
function flashLoan(
IERC3156FlashBorrower receiver,
address token,
uint amount,
bytes memory userData
) external override nonReentrant whenNotPaused returns (bool) {
uint preLoanBalance = IERC20(token).balanceOf(address(this));
uint feeAmount = _calculateFlashLoanFeeAmount(amount);
require(preLoanBalance >= amount, "INSUFFICIENT_FLASH_LOAN_BALANCE");
TransferHelper.safeTransfer(token, address(receiver), amount);
require(
receiver.onFlashLoan(msg.sender, token, amount, feeAmount, userData) == ERC3156_CALLBACK_SUCCESS,
"IERC3156_CALLBACK_FAILED"
);
// Checking for loan repayment first (without accounting for fees) makes for simpler debugging, and results
// in more accurate revert reasons if the flash loan protocol fee percentage is zero.
uint postLoanBalance = IERC20(token).balanceOf(address(this));
require(postLoanBalance >= preLoanBalance, "INVALID_POST_LOAN_BALANCE");
// No need for checked arithmetic since we know the loan was fully repaid.
uint receivedFeeAmount = postLoanBalance - preLoanBalance;
require(receivedFeeAmount >= feeAmount, "INSUFFICIENT_FLASH_LOAN_FEE_AMOUNT");
_payFeeAmount(token, receivedFeeAmount);
emit FlashLoan(address(receiver), token, amount, receivedFeeAmount);
return true;
}
}{
"optimizer": {
"enabled": true,
"runs": 200,
"details": {
"yul": false
}
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_wETH","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ETHTransferFailed","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"TransferFromFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeAmount","type":"uint256"}],"name":"FlashLoan","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldFlashLoanFeePercentage","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newFlashLoanFeePercentage","type":"uint256"}],"name":"FlashLoanFeePercentageChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"ERC3156_CALLBACK_SUCCESS","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"depositETH","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"flashFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC3156FlashBorrower","name":"receiver","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"flashLoan","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flashLoanFeePercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flashLoanFeeRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IFlashLoanRecipient","name":"recipient","type":"address"},{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"flashLoanMultiple","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"maxFlashLoan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"reserves","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFlashLoanFeePercentage","type":"uint256"}],"name":"setFlashLoanFeePercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_flashLoanFeeRecipient","type":"address"}],"name":"setFlashLoanFeeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_status","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferAndDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint8","name":"mode","type":"uint8"}],"name":"withdrawAlternative","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60a06040526601c6bf526340006002553480156200001c57600080fd5b5060405162002b1c38038062002b1c8339810160408190526200003f9162000134565b6001600055336200005081620000a8565b6001600160a01b038116620000825760405162461bcd60e51b8152600401620000799062000161565b60405180910390fd5b600380546001600160a01b0319166001600160a01b03928316179055166080526200019c565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006001600160a01b0382165b92915050565b6200011881620000fa565b81146200012457600080fd5b50565b805162000107816200010d565b6000602082840312156200014b576200014b600080fd5b600062000159848462000127565b949350505050565b60208082528181019081527f494e56414c49445f464c4153485f4c4f414e5f4645455f524543495049454e5460408301526060820162000107565b608051612909620002136000396000818161015f01528181610441015281816104dd0152818161052f015281816105bf015281816109320152818161098401528181610a1801528181610f4f01528181611089015281816116180152818161171201528181611b420152611bc801526129096000f3fe60806040526004361061014f5760003560e01c8063b914cc64116100b6578063d9d98ce41161006f578063d9d98ce4146103db578063ec85b12b146103fb578063f24286211461042f578063f2fde38b14610463578063f7888aec14610483578063f9609f08146104a357600080fd5b8063b914cc6414610318578063beabacc814610338578063c499f8ce14610358578063cfaa541e1461036e578063d66bd5241461038e578063d9caed12146103bb57600080fd5b8063613255ab11610108578063613255ab1461025c5780636b6b9f691461027c5780636cb568c11461029c578063715018a6146102bc5780638da5cb5b146102d1578063a16e5112146102f857600080fd5b806316c38b3c146101985780632d2da806146101b85780634782f779146101e1578063511de15b146102015780635c975abb146102145780635cffe9de1461023c57600080fd5b3661019357336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146101915761018f6000336104b1565b505b005b600080fd5b3480156101a457600080fd5b506101916101b3366004611cb1565b61071f565b6101cb6101c6366004611cf7565b6107cf565b6040516101d89190611d20565b60405180910390f35b3480156101ed57600080fd5b506101916101fc366004611d3f565b610868565b6101cb61020f366004611d7c565b6108fc565b34801561022057600080fd5b50600154600160a01b900460ff165b6040516101d89190611dd4565b34801561024857600080fd5b5061022f610257366004611ef7565b610b87565b34801561026857600080fd5b506101cb610277366004611cf7565b610e33565b34801561028857600080fd5b50610191610297366004611f76565b610ea3565b3480156102a857600080fd5b506101916102b7366004611fab565b610f13565b3480156102c857600080fd5b5061019161101b565b3480156102dd57600080fd5b506001546001600160a01b03165b6040516101d8919061200c565b34801561030457600080fd5b506003546102eb906001600160a01b031681565b34801561032457600080fd5b50610191610333366004611cf7565b61102f565b34801561034457600080fd5b50610191610353366004611d7c565b61107f565b34801561036457600080fd5b506101cb60025481565b34801561037a57600080fd5b50610191610389366004612132565b611137565b34801561039a57600080fd5b506101cb6103a9366004611cf7565b60056020526000908152604090205481565b3480156103c757600080fd5b506101916103d6366004611d7c565b6115f1565b3480156103e757600080fd5b506101cb6103f6366004611d3f565b6116c9565b34801561040757600080fd5b506101cb7f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd981565b34801561043b57600080fd5b506102eb7f000000000000000000000000000000000000000000000000000000000000000081565b34801561046f57600080fd5b5061019161047e366004611cf7565b6116d4565b34801561048f57600080fd5b506101cb61049e3660046121af565b61170e565b6101cb6104b13660046121af565b60006104bb61177a565b6001600160a01b0383166104d05750346106b7565b34156104db57600080fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b03160361062b576040516370a0823160e01b8152600093506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a082319061056490309060040161200c565b602060405180830381865afa158015610581573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a591906121ed565b604051632e1a7d4d60e01b81529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632e1a7d4d906105f4908490600401611d20565b600060405180830381600087803b15801561060e57600080fd5b505af1158015610622573d6000803e3d6000fd5b505050506106b7565b6001600160a01b038316600081815260056020526040908190205490516370a0823160e01b81529091906370a082319061066990309060040161200c565b602060405180830381865afa158015610686573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106aa91906121ed565b6106b49190612224565b90505b6001600160a01b038316600090815260056020526040812080548392906106df90849061223b565b90915550506001600160a01b0380841660009081526004602090815260408083209386168352929052208054820190556107196001600055565b92915050565b6107276117a3565b8015610771576107356117dc565b7f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25833604051610764919061200c565b60405180910390a16107b1565b610779611806565b7f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa336040516107a8919061200c565b60405180910390a15b60018054911515600160a01b0260ff60a01b19909216919091179055565b60006107d961177a565b50600080805260056020527f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746bc8054349283929161081790849061223b565b90915550506001600160a01b03821660009081527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ec602052604090208054820190556108636001600055565b919050565b61087061177a565b61087a828261182f565b3360009081527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ec6020526040812080548392906108b8908490612224565b90915550506000805260056020527f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746bc805482900390556108f86001600055565b5050565b600061090661177a565b6001600160a01b0384166109255734821461092057600080fd5b610b1c565b341561093057600080fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b031603610a84576040516323b872dd60e01b8152600094506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906323b872dd906109bd90339030908790600401612253565b6020604051808303816000875af11580156109dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a009190612286565b50604051632e1a7d4d60e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632e1a7d4d90610a4d908590600401611d20565b600060405180830381600087803b158015610a6757600080fd5b505af1158015610a7b573d6000803e3d6000fd5b50505050610b1c565b610a90843330856118ac565b6001600160a01b038416600081815260056020526040908190205490516370a0823160e01b81529091906370a0823190610ace90309060040161200c565b602060405180830381865afa158015610aeb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0f91906121ed565b610b199190612224565b91505b6001600160a01b03841660009081526005602052604081208054849290610b4490849061223b565b9091555050506001600160a01b03808416600090815260046020908152604080832093861683529290522080548201905580610b806001600055565b9392505050565b6000610b9161177a565b610b996117dc565b6040516370a0823160e01b81526000906001600160a01b038616906370a0823190610bc890309060040161200c565b602060405180830381865afa158015610be5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0991906121ed565b90506000610c16856119a2565b905084821015610c415760405162461bcd60e51b8152600401610c38906122de565b60405180910390fd5b610c4c8688876119c5565b6040516323e30c8b60e01b81527f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd9906001600160a01b038916906323e30c8b90610ca29033908b908b9088908c9060040161234c565b6020604051808303816000875af1158015610cc1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce591906121ed565b14610d025760405162461bcd60e51b8152600401610c38906123d2565b6040516370a0823160e01b81526000906001600160a01b038816906370a0823190610d3190309060040161200c565b602060405180830381865afa158015610d4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7291906121ed565b905082811015610d945760405162461bcd60e51b8152600401610c3890612416565b6000610da08483612224565b905082811015610dc25760405162461bcd60e51b8152600401610c3890612468565b610dcc8882611ab8565b876001600160a01b0316896001600160a01b03167f0d7d75e01ab95780d3cd1c8ec0dd6c2ce19e3a20427eec8bf53283b6fb8e95f08984604051610e11929190612478565b60405180910390a36001945050505050610e2b6001600055565b949350505050565b6040516370a0823160e01b81526000906001600160a01b038316906370a0823190610e6290309060040161200c565b602060405180830381865afa158015610e7f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071991906121ed565b610eab6117a3565b67016345785d8a0000811115610ed35760405162461bcd60e51b8152600401610c38906124d2565b7f36e8f57c180167765b2da71700ae4d0d3237d63cd1552cefa8bafca7c1d3fc3d60025482604051610f06929190612478565b60405180910390a1600255565b610f1b61177a565b6001600160a01b038416610f4d578060ff16600203610f4357610f3e8383611b40565b610fb4565b610f3e838361182f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b031603610fa957600093508060ff16600103610f9f57610f3e838361182f565b610f3e8383611b40565b610fb48484846119c5565b6001600160a01b038416600090815260046020908152604080832033845290915281208054849290610fe7908490612224565b90915550506001600160a01b0384166000908152600560205260409020805483900390556110156001600055565b50505050565b6110236117a3565b61102d6000611c45565b565b6110376117a3565b6001600160a01b03811661105d5760405162461bcd60e51b8152600401610c3890612514565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b61108761177a565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316036110c557600092505b6001600160a01b0383166000908152600460209081526040808320338452909152812080548392906110f8908490612224565b90915550506001600160a01b0380841660009081526004602090815260408083209386168352929052208054820190556111326001600055565b505050565b61113f61177a565b6111476117dc565b8251825181146111695760405162461bcd60e51b8152600401610c3890612550565b60008167ffffffffffffffff81111561118457611184611e01565b6040519080825280602002602001820160405280156111ad578160200160208202803683370190505b50905060008267ffffffffffffffff8111156111cb576111cb611e01565b6040519080825280602002602001820160405280156111f4578160200160208202803683370190505b5090506000806000805b868310156113e15789838151811061121857611218612560565b6020026020010151915088838151811061123457611234612560565b60200260200101519050836001600160a01b0316826001600160a01b03161160006001600160a01b0316836001600160a01b03161461129a576040518060400160405280600f81526020016e554e534f525445445f544f4b454e5360881b8152506112be565b6040518060400160405280600a8152602001692d22a927afaa27a5a2a760b11b8152505b906112dc5760405162461bcd60e51b8152600401610c389190612576565b50819350816001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161130c919061200c565b602060405180830381865afa158015611329573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134d91906121ed565b85848151811061135f5761135f612560565b602002602001018181525050611374816119a2565b86848151811061138657611386612560565b602002602001018181525050808584815181106113a5576113a5612560565b602002602001015110156113cb5760405162461bcd60e51b8152600401610c38906122de565b6113d6828c836119c5565b8260010192506111fe565b60405163f04f270760e01b81526001600160a01b038c169063f04f270790611413908d908d908b908e9060040161262e565b600060405180830381600087803b15801561142d57600080fd5b505af1158015611441573d6000803e3d6000fd5b5050505060008060008095505b898610156115dd578c868151811061146857611468612560565b6020026020010151945087868151811061148457611484612560565b60200260200101519250846001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016114ba919061200c565b602060405180830381865afa1580156114d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114fb91906121ed565b91508282101561151d5760405162461bcd60e51b8152600401610c3890612416565b6115278383612224565b905088868151811061153b5761153b612560565b60200260200101518110156115625760405162461bcd60e51b8152600401610c3890612468565b61156c8582611ab8565b846001600160a01b03168e6001600160a01b03167f0d7d75e01ab95780d3cd1c8ec0dd6c2ce19e3a20427eec8bf53283b6fb8e95f08e89815181106115b3576115b3612560565b6020026020010151846040516115ca929190612478565b60405180910390a385600101955061144e565b505050505050505050506110156001600055565b6115f961177a565b6001600160a01b03831661161657611611828261182f565b611668565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b03160361165d57600092506116118282611b40565b6116688383836119c5565b6001600160a01b03831660009081526004602090815260408083203384529091528120805483929061169b908490612224565b90915550506001600160a01b0383166000908152600560205260409020805482900390556111326001600055565b6000610b80826119a2565b6116dc6117a3565b6001600160a01b0381166117025760405162461bcd60e51b8152600401610c38906126c8565b61170b81611c45565b50565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b03160361174e57600092505b506001600160a01b03918216600090815260046020908152604080832093909416825291909152205490565b60026000540361179c5760405162461bcd60e51b8152600401610c389061270c565b6002600055565b336117b66001546001600160a01b031690565b6001600160a01b03161461102d5760405162461bcd60e51b8152600401610c389061274e565b600154600160a01b900460ff161561102d5760405162461bcd60e51b8152600401610c3890612785565b600154600160a01b900460ff1661102d5760405162461bcd60e51b8152600401610c38906127c0565b6000826001600160a01b031682604051611848906127da565b60006040518083038185875af1925050503d8060008114611885576040519150601f19603f3d011682016040523d82523d6000602084013e61188a565b606091505b50509050806111325760405163b12d13eb60e01b815260040160405180910390fd5b600080856001600160a01b03166323b872dd8686866040516024016118d393929190612253565b6040516020818303038152906040529060e01b6020820180516001600160e01b03838183161783525050505060405161190c9190612807565b6000604051808303816000865af19150503d8060008114611949576040519150601f19603f3d011682016040523d82523d6000602084013e61194e565b606091505b509150915081158061197c575080511580159061197c57508080602001905181019061197a9190612286565b155b1561199a57604051631e4e7d0960e21b815260040160405180910390fd5b505050505050565b6000670de0b6b3a7640000600254836119bb9190612813565b6107199190612848565b600080846001600160a01b031663a9059cbb85856040516024016119ea92919061285c565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051611a239190612807565b6000604051808303816000865af19150503d8060008114611a60576040519150601f19603f3d011682016040523d82523d6000602084013e611a65565b606091505b5091509150811580611a935750805115801590611a93575080806020019051810190611a919190612286565b155b15611ab1576040516312171d8360e31b815260040160405180910390fd5b5050505050565b80156108f8576003546001600160a01b0316611ad58382846119c5565b600254604051631087d04360e31b81526001600160a01b0383169163843e821891611b0991600a918891889160040161288d565b600060405180830381600087803b158015611b2357600080fd5b505af1158015611b37573d6000803e3d6000fd5b50505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015611b9b57600080fd5b505af1158015611baf573d6000803e3d6000fd5b505060405163a9059cbb60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016935063a9059cbb9250611c0291508590859060040161285c565b6020604051808303816000875af1158015611c21573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111329190612286565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8015155b811461170b57600080fd5b803561071981611c97565b600060208284031215611cc657611cc6600080fd5b6000610e2b8484611ca6565b60006001600160a01b038216610719565b611c9b81611cd2565b803561071981611ce3565b600060208284031215611d0c57611d0c600080fd5b6000610e2b8484611cec565b805b82525050565b602081016107198284611d18565b80611c9b565b803561071981611d2e565b60008060408385031215611d5557611d55600080fd5b6000611d618585611cec565b9250506020611d7285828601611d34565b9150509250929050565b600080600060608486031215611d9457611d94600080fd5b6000611da08686611cec565b9350506020611db186828701611cec565b9250506040611dc286828701611d34565b9150509250925092565b801515611d1a565b602081016107198284611dcc565b600061071982611cd2565b611c9b81611de2565b803561071981611ded565b634e487b7160e01b600052604160045260246000fd5b601f19601f830116810181811067ffffffffffffffff82111715611e3d57611e3d611e01565b6040525050565b6000611e4f60405190565b90506108638282611e17565b600067ffffffffffffffff821115611e7557611e75611e01565b601f19601f83011660200192915050565b82818337506000910152565b6000611ea5611ea084611e5b565b611e44565b905082815260208101848484011115611ec057611ec0600080fd5b611ecb848285611e86565b509392505050565b600082601f830112611ee757611ee7600080fd5b8135610e2b848260208601611e92565b60008060008060808587031215611f1057611f10600080fd5b6000611f1c8787611df6565b9450506020611f2d87828801611cec565b9350506040611f3e87828801611d34565b925050606085013567ffffffffffffffff811115611f5e57611f5e600080fd5b611f6a87828801611ed3565b91505092959194509250565b600060208284031215611f8b57611f8b600080fd5b6000610e2b8484611d34565b60ff8116611c9b565b803561071981611f97565b60008060008060808587031215611fc457611fc4600080fd5b6000611fd08787611cec565b9450506020611fe187828801611cec565b9350506040611ff287828801611d34565b9250506060611f6a87828801611fa0565b611d1a81611cd2565b602081016107198284612003565b600067ffffffffffffffff82111561203457612034611e01565b5060209081020190565b600061204c611ea08461201a565b8381529050602080820190840283018581111561206b5761206b600080fd5b835b8181101561208f57806120808882611cec565b8452506020928301920161206d565b5050509392505050565b600082601f8301126120ad576120ad600080fd5b8135610e2b84826020860161203e565b60006120cb611ea08461201a565b838152905060208082019084028301858111156120ea576120ea600080fd5b835b8181101561208f57806120ff8882611d34565b845250602092830192016120ec565b600082601f83011261212257612122600080fd5b8135610e2b8482602086016120bd565b6000806000806080858703121561214b5761214b600080fd5b60006121578787611df6565b945050602085013567ffffffffffffffff81111561217757612177600080fd5b61218387828801612099565b935050604085013567ffffffffffffffff8111156121a3576121a3600080fd5b611f3e8782880161210e565b600080604083850312156121c5576121c5600080fd5b60006121d18585611cec565b9250506020611d7285828601611cec565b805161071981611d2e565b60006020828403121561220257612202600080fd5b6000610e2b84846121e2565b634e487b7160e01b600052601160045260246000fd5b6000828210156122365761223661220e565b500390565b6000821982111561224e5761224e61220e565b500190565b606081016122618286612003565b61226e6020830185612003565b610e2b6040830184611d18565b805161071981611c97565b60006020828403121561229b5761229b600080fd5b6000610e2b848461227b565b601f81526000602082017f494e53554646494349454e545f464c4153485f4c4f414e5f42414c414e434500815291505b5060200190565b60208082528101610719816122a7565b60005b838110156123095781810151838201526020016122f1565b838111156110155750506000910152565b6000612324825190565b80845260208401935061233b8185602086016122ee565b601f01601f19169290920192915050565b60a0810161235a8288612003565b6123676020830187612003565b6123746040830186611d18565b6123816060830185611d18565b8181036080830152612393818461231a565b979650505050505050565b601881526000602082017f49455243333135365f43414c4c4241434b5f4641494c45440000000000000000815291506122d7565b602080825281016107198161239e565b601981526000602082017f494e56414c49445f504f53545f4c4f414e5f42414c414e434500000000000000815291506122d7565b60208082528101610719816123e2565b602281526000602082017f494e53554646494349454e545f464c4153485f4c4f414e5f4645455f414d4f55815261139560f21b602082015291505b5060400190565b6020808252810161071981612426565b604081016124868285611d18565b610b806020830184611d18565b602281526000602082017f464c4153485f4c4f414e5f4645455f50455243454e544147455f544f4f5f484981526108e960f31b60208201529150612461565b6020808252810161071981612493565b60208082527f494e56414c49445f464c4153485f4c4f414e5f4645455f524543495049454e54910190815260006122d7565b60208082528101610719816124e2565b60158152600060208201740929ca0aaa8be988a9c8ea890be9a92a69a82a8869605b1b815291506122d7565b6020808252810161071981612524565b634e487b7160e01b600052603260045260246000fd5b60208082528101610b80818461231a565b60006125938383612003565b505060200190565b60006125a5825190565b80845260209384019383018060005b838110156125d95781516125c88882612587565b9750602083019250506001016125b4565b509495945050505050565b60006125938383611d18565b60006125fa825190565b80845260209384019383018060005b838110156125d957815161261d88826125e4565b975060208301925050600101612609565b6080808252810161263f818761259b565b9050818103602083015261265381866125f0565b9050818103604083015261266781856125f0565b9050818103606083015261267b818461231a565b9695505050505050565b602681526000602082017f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b60208201529150612461565b6020808252810161071981612685565b601f81526000602082017f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00815291506122d7565b60208082528101610719816126d8565b60208082527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572910190815260006122d7565b602080825281016107198161271c565b601081526000602082016f14185d5cd8589b194e881c185d5cd95960821b815291506122d7565b602080825281016107198161275e565b601481526000602082017314185d5cd8589b194e881b9bdd081c185d5cd95960621b815291506122d7565b6020808252810161071981612795565b6000815b91505090565b6000610719826127d0565b60006127ef825190565b6127fd8185602086016122ee565b9290920192915050565b6000610b8082846127e5565b600081600019048311821515161561282d5761282d61220e565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261285757612857612832565b500490565b604081016124868285612003565b600061ffff8216610719565b611d1a8161286a565b6000808252602082016127d4565b60a0810161289b8287612876565b6128a86020830186612003565b6128b56040830185611d18565b6128c26060830184611d18565b818103608083015261267b8161287f56fea26469706673582212208539bcd7e1382783133f2080efcd30632940d2710efb2f5de93727ff03fcb9f464736f6c634300080f0033000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f
Deployed Bytecode
0x60806040526004361061014f5760003560e01c8063b914cc64116100b6578063d9d98ce41161006f578063d9d98ce4146103db578063ec85b12b146103fb578063f24286211461042f578063f2fde38b14610463578063f7888aec14610483578063f9609f08146104a357600080fd5b8063b914cc6414610318578063beabacc814610338578063c499f8ce14610358578063cfaa541e1461036e578063d66bd5241461038e578063d9caed12146103bb57600080fd5b8063613255ab11610108578063613255ab1461025c5780636b6b9f691461027c5780636cb568c11461029c578063715018a6146102bc5780638da5cb5b146102d1578063a16e5112146102f857600080fd5b806316c38b3c146101985780632d2da806146101b85780634782f779146101e1578063511de15b146102015780635c975abb146102145780635cffe9de1461023c57600080fd5b3661019357336001600160a01b037f000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f16146101915761018f6000336104b1565b505b005b600080fd5b3480156101a457600080fd5b506101916101b3366004611cb1565b61071f565b6101cb6101c6366004611cf7565b6107cf565b6040516101d89190611d20565b60405180910390f35b3480156101ed57600080fd5b506101916101fc366004611d3f565b610868565b6101cb61020f366004611d7c565b6108fc565b34801561022057600080fd5b50600154600160a01b900460ff165b6040516101d89190611dd4565b34801561024857600080fd5b5061022f610257366004611ef7565b610b87565b34801561026857600080fd5b506101cb610277366004611cf7565b610e33565b34801561028857600080fd5b50610191610297366004611f76565b610ea3565b3480156102a857600080fd5b506101916102b7366004611fab565b610f13565b3480156102c857600080fd5b5061019161101b565b3480156102dd57600080fd5b506001546001600160a01b03165b6040516101d8919061200c565b34801561030457600080fd5b506003546102eb906001600160a01b031681565b34801561032457600080fd5b50610191610333366004611cf7565b61102f565b34801561034457600080fd5b50610191610353366004611d7c565b61107f565b34801561036457600080fd5b506101cb60025481565b34801561037a57600080fd5b50610191610389366004612132565b611137565b34801561039a57600080fd5b506101cb6103a9366004611cf7565b60056020526000908152604090205481565b3480156103c757600080fd5b506101916103d6366004611d7c565b6115f1565b3480156103e757600080fd5b506101cb6103f6366004611d3f565b6116c9565b34801561040757600080fd5b506101cb7f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd981565b34801561043b57600080fd5b506102eb7f000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f81565b34801561046f57600080fd5b5061019161047e366004611cf7565b6116d4565b34801561048f57600080fd5b506101cb61049e3660046121af565b61170e565b6101cb6104b13660046121af565b60006104bb61177a565b6001600160a01b0383166104d05750346106b7565b34156104db57600080fd5b7f000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f6001600160a01b0316836001600160a01b03160361062b576040516370a0823160e01b8152600093506001600160a01b037f000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f16906370a082319061056490309060040161200c565b602060405180830381865afa158015610581573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a591906121ed565b604051632e1a7d4d60e01b81529091506001600160a01b037f000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f1690632e1a7d4d906105f4908490600401611d20565b600060405180830381600087803b15801561060e57600080fd5b505af1158015610622573d6000803e3d6000fd5b505050506106b7565b6001600160a01b038316600081815260056020526040908190205490516370a0823160e01b81529091906370a082319061066990309060040161200c565b602060405180830381865afa158015610686573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106aa91906121ed565b6106b49190612224565b90505b6001600160a01b038316600090815260056020526040812080548392906106df90849061223b565b90915550506001600160a01b0380841660009081526004602090815260408083209386168352929052208054820190556107196001600055565b92915050565b6107276117a3565b8015610771576107356117dc565b7f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25833604051610764919061200c565b60405180910390a16107b1565b610779611806565b7f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa336040516107a8919061200c565b60405180910390a15b60018054911515600160a01b0260ff60a01b19909216919091179055565b60006107d961177a565b50600080805260056020527f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746bc8054349283929161081790849061223b565b90915550506001600160a01b03821660009081527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ec602052604090208054820190556108636001600055565b919050565b61087061177a565b61087a828261182f565b3360009081527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ec6020526040812080548392906108b8908490612224565b90915550506000805260056020527f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746bc805482900390556108f86001600055565b5050565b600061090661177a565b6001600160a01b0384166109255734821461092057600080fd5b610b1c565b341561093057600080fd5b7f000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f6001600160a01b0316846001600160a01b031603610a84576040516323b872dd60e01b8152600094506001600160a01b037f000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f16906323b872dd906109bd90339030908790600401612253565b6020604051808303816000875af11580156109dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a009190612286565b50604051632e1a7d4d60e01b81526001600160a01b037f000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f1690632e1a7d4d90610a4d908590600401611d20565b600060405180830381600087803b158015610a6757600080fd5b505af1158015610a7b573d6000803e3d6000fd5b50505050610b1c565b610a90843330856118ac565b6001600160a01b038416600081815260056020526040908190205490516370a0823160e01b81529091906370a0823190610ace90309060040161200c565b602060405180830381865afa158015610aeb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0f91906121ed565b610b199190612224565b91505b6001600160a01b03841660009081526005602052604081208054849290610b4490849061223b565b9091555050506001600160a01b03808416600090815260046020908152604080832093861683529290522080548201905580610b806001600055565b9392505050565b6000610b9161177a565b610b996117dc565b6040516370a0823160e01b81526000906001600160a01b038616906370a0823190610bc890309060040161200c565b602060405180830381865afa158015610be5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0991906121ed565b90506000610c16856119a2565b905084821015610c415760405162461bcd60e51b8152600401610c38906122de565b60405180910390fd5b610c4c8688876119c5565b6040516323e30c8b60e01b81527f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd9906001600160a01b038916906323e30c8b90610ca29033908b908b9088908c9060040161234c565b6020604051808303816000875af1158015610cc1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce591906121ed565b14610d025760405162461bcd60e51b8152600401610c38906123d2565b6040516370a0823160e01b81526000906001600160a01b038816906370a0823190610d3190309060040161200c565b602060405180830381865afa158015610d4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7291906121ed565b905082811015610d945760405162461bcd60e51b8152600401610c3890612416565b6000610da08483612224565b905082811015610dc25760405162461bcd60e51b8152600401610c3890612468565b610dcc8882611ab8565b876001600160a01b0316896001600160a01b03167f0d7d75e01ab95780d3cd1c8ec0dd6c2ce19e3a20427eec8bf53283b6fb8e95f08984604051610e11929190612478565b60405180910390a36001945050505050610e2b6001600055565b949350505050565b6040516370a0823160e01b81526000906001600160a01b038316906370a0823190610e6290309060040161200c565b602060405180830381865afa158015610e7f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071991906121ed565b610eab6117a3565b67016345785d8a0000811115610ed35760405162461bcd60e51b8152600401610c38906124d2565b7f36e8f57c180167765b2da71700ae4d0d3237d63cd1552cefa8bafca7c1d3fc3d60025482604051610f06929190612478565b60405180910390a1600255565b610f1b61177a565b6001600160a01b038416610f4d578060ff16600203610f4357610f3e8383611b40565b610fb4565b610f3e838361182f565b7f000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f6001600160a01b0316846001600160a01b031603610fa957600093508060ff16600103610f9f57610f3e838361182f565b610f3e8383611b40565b610fb48484846119c5565b6001600160a01b038416600090815260046020908152604080832033845290915281208054849290610fe7908490612224565b90915550506001600160a01b0384166000908152600560205260409020805483900390556110156001600055565b50505050565b6110236117a3565b61102d6000611c45565b565b6110376117a3565b6001600160a01b03811661105d5760405162461bcd60e51b8152600401610c3890612514565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b61108761177a565b7f000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f6001600160a01b0316836001600160a01b0316036110c557600092505b6001600160a01b0383166000908152600460209081526040808320338452909152812080548392906110f8908490612224565b90915550506001600160a01b0380841660009081526004602090815260408083209386168352929052208054820190556111326001600055565b505050565b61113f61177a565b6111476117dc565b8251825181146111695760405162461bcd60e51b8152600401610c3890612550565b60008167ffffffffffffffff81111561118457611184611e01565b6040519080825280602002602001820160405280156111ad578160200160208202803683370190505b50905060008267ffffffffffffffff8111156111cb576111cb611e01565b6040519080825280602002602001820160405280156111f4578160200160208202803683370190505b5090506000806000805b868310156113e15789838151811061121857611218612560565b6020026020010151915088838151811061123457611234612560565b60200260200101519050836001600160a01b0316826001600160a01b03161160006001600160a01b0316836001600160a01b03161461129a576040518060400160405280600f81526020016e554e534f525445445f544f4b454e5360881b8152506112be565b6040518060400160405280600a8152602001692d22a927afaa27a5a2a760b11b8152505b906112dc5760405162461bcd60e51b8152600401610c389190612576565b50819350816001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161130c919061200c565b602060405180830381865afa158015611329573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134d91906121ed565b85848151811061135f5761135f612560565b602002602001018181525050611374816119a2565b86848151811061138657611386612560565b602002602001018181525050808584815181106113a5576113a5612560565b602002602001015110156113cb5760405162461bcd60e51b8152600401610c38906122de565b6113d6828c836119c5565b8260010192506111fe565b60405163f04f270760e01b81526001600160a01b038c169063f04f270790611413908d908d908b908e9060040161262e565b600060405180830381600087803b15801561142d57600080fd5b505af1158015611441573d6000803e3d6000fd5b5050505060008060008095505b898610156115dd578c868151811061146857611468612560565b6020026020010151945087868151811061148457611484612560565b60200260200101519250846001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016114ba919061200c565b602060405180830381865afa1580156114d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114fb91906121ed565b91508282101561151d5760405162461bcd60e51b8152600401610c3890612416565b6115278383612224565b905088868151811061153b5761153b612560565b60200260200101518110156115625760405162461bcd60e51b8152600401610c3890612468565b61156c8582611ab8565b846001600160a01b03168e6001600160a01b03167f0d7d75e01ab95780d3cd1c8ec0dd6c2ce19e3a20427eec8bf53283b6fb8e95f08e89815181106115b3576115b3612560565b6020026020010151846040516115ca929190612478565b60405180910390a385600101955061144e565b505050505050505050506110156001600055565b6115f961177a565b6001600160a01b03831661161657611611828261182f565b611668565b7f000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f6001600160a01b0316836001600160a01b03160361165d57600092506116118282611b40565b6116688383836119c5565b6001600160a01b03831660009081526004602090815260408083203384529091528120805483929061169b908490612224565b90915550506001600160a01b0383166000908152600560205260409020805482900390556111326001600055565b6000610b80826119a2565b6116dc6117a3565b6001600160a01b0381166117025760405162461bcd60e51b8152600401610c38906126c8565b61170b81611c45565b50565b60007f000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f6001600160a01b0316836001600160a01b03160361174e57600092505b506001600160a01b03918216600090815260046020908152604080832093909416825291909152205490565b60026000540361179c5760405162461bcd60e51b8152600401610c389061270c565b6002600055565b336117b66001546001600160a01b031690565b6001600160a01b03161461102d5760405162461bcd60e51b8152600401610c389061274e565b600154600160a01b900460ff161561102d5760405162461bcd60e51b8152600401610c3890612785565b600154600160a01b900460ff1661102d5760405162461bcd60e51b8152600401610c38906127c0565b6000826001600160a01b031682604051611848906127da565b60006040518083038185875af1925050503d8060008114611885576040519150601f19603f3d011682016040523d82523d6000602084013e61188a565b606091505b50509050806111325760405163b12d13eb60e01b815260040160405180910390fd5b600080856001600160a01b03166323b872dd8686866040516024016118d393929190612253565b6040516020818303038152906040529060e01b6020820180516001600160e01b03838183161783525050505060405161190c9190612807565b6000604051808303816000865af19150503d8060008114611949576040519150601f19603f3d011682016040523d82523d6000602084013e61194e565b606091505b509150915081158061197c575080511580159061197c57508080602001905181019061197a9190612286565b155b1561199a57604051631e4e7d0960e21b815260040160405180910390fd5b505050505050565b6000670de0b6b3a7640000600254836119bb9190612813565b6107199190612848565b600080846001600160a01b031663a9059cbb85856040516024016119ea92919061285c565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051611a239190612807565b6000604051808303816000865af19150503d8060008114611a60576040519150601f19603f3d011682016040523d82523d6000602084013e611a65565b606091505b5091509150811580611a935750805115801590611a93575080806020019051810190611a919190612286565b155b15611ab1576040516312171d8360e31b815260040160405180910390fd5b5050505050565b80156108f8576003546001600160a01b0316611ad58382846119c5565b600254604051631087d04360e31b81526001600160a01b0383169163843e821891611b0991600a918891889160040161288d565b600060405180830381600087803b158015611b2357600080fd5b505af1158015611b37573d6000803e3d6000fd5b50505050505050565b7f000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f6001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015611b9b57600080fd5b505af1158015611baf573d6000803e3d6000fd5b505060405163a9059cbb60e01b81526001600160a01b037f000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f16935063a9059cbb9250611c0291508590859060040161285c565b6020604051808303816000875af1158015611c21573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111329190612286565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8015155b811461170b57600080fd5b803561071981611c97565b600060208284031215611cc657611cc6600080fd5b6000610e2b8484611ca6565b60006001600160a01b038216610719565b611c9b81611cd2565b803561071981611ce3565b600060208284031215611d0c57611d0c600080fd5b6000610e2b8484611cec565b805b82525050565b602081016107198284611d18565b80611c9b565b803561071981611d2e565b60008060408385031215611d5557611d55600080fd5b6000611d618585611cec565b9250506020611d7285828601611d34565b9150509250929050565b600080600060608486031215611d9457611d94600080fd5b6000611da08686611cec565b9350506020611db186828701611cec565b9250506040611dc286828701611d34565b9150509250925092565b801515611d1a565b602081016107198284611dcc565b600061071982611cd2565b611c9b81611de2565b803561071981611ded565b634e487b7160e01b600052604160045260246000fd5b601f19601f830116810181811067ffffffffffffffff82111715611e3d57611e3d611e01565b6040525050565b6000611e4f60405190565b90506108638282611e17565b600067ffffffffffffffff821115611e7557611e75611e01565b601f19601f83011660200192915050565b82818337506000910152565b6000611ea5611ea084611e5b565b611e44565b905082815260208101848484011115611ec057611ec0600080fd5b611ecb848285611e86565b509392505050565b600082601f830112611ee757611ee7600080fd5b8135610e2b848260208601611e92565b60008060008060808587031215611f1057611f10600080fd5b6000611f1c8787611df6565b9450506020611f2d87828801611cec565b9350506040611f3e87828801611d34565b925050606085013567ffffffffffffffff811115611f5e57611f5e600080fd5b611f6a87828801611ed3565b91505092959194509250565b600060208284031215611f8b57611f8b600080fd5b6000610e2b8484611d34565b60ff8116611c9b565b803561071981611f97565b60008060008060808587031215611fc457611fc4600080fd5b6000611fd08787611cec565b9450506020611fe187828801611cec565b9350506040611ff287828801611d34565b9250506060611f6a87828801611fa0565b611d1a81611cd2565b602081016107198284612003565b600067ffffffffffffffff82111561203457612034611e01565b5060209081020190565b600061204c611ea08461201a565b8381529050602080820190840283018581111561206b5761206b600080fd5b835b8181101561208f57806120808882611cec565b8452506020928301920161206d565b5050509392505050565b600082601f8301126120ad576120ad600080fd5b8135610e2b84826020860161203e565b60006120cb611ea08461201a565b838152905060208082019084028301858111156120ea576120ea600080fd5b835b8181101561208f57806120ff8882611d34565b845250602092830192016120ec565b600082601f83011261212257612122600080fd5b8135610e2b8482602086016120bd565b6000806000806080858703121561214b5761214b600080fd5b60006121578787611df6565b945050602085013567ffffffffffffffff81111561217757612177600080fd5b61218387828801612099565b935050604085013567ffffffffffffffff8111156121a3576121a3600080fd5b611f3e8782880161210e565b600080604083850312156121c5576121c5600080fd5b60006121d18585611cec565b9250506020611d7285828601611cec565b805161071981611d2e565b60006020828403121561220257612202600080fd5b6000610e2b84846121e2565b634e487b7160e01b600052601160045260246000fd5b6000828210156122365761223661220e565b500390565b6000821982111561224e5761224e61220e565b500190565b606081016122618286612003565b61226e6020830185612003565b610e2b6040830184611d18565b805161071981611c97565b60006020828403121561229b5761229b600080fd5b6000610e2b848461227b565b601f81526000602082017f494e53554646494349454e545f464c4153485f4c4f414e5f42414c414e434500815291505b5060200190565b60208082528101610719816122a7565b60005b838110156123095781810151838201526020016122f1565b838111156110155750506000910152565b6000612324825190565b80845260208401935061233b8185602086016122ee565b601f01601f19169290920192915050565b60a0810161235a8288612003565b6123676020830187612003565b6123746040830186611d18565b6123816060830185611d18565b8181036080830152612393818461231a565b979650505050505050565b601881526000602082017f49455243333135365f43414c4c4241434b5f4641494c45440000000000000000815291506122d7565b602080825281016107198161239e565b601981526000602082017f494e56414c49445f504f53545f4c4f414e5f42414c414e434500000000000000815291506122d7565b60208082528101610719816123e2565b602281526000602082017f494e53554646494349454e545f464c4153485f4c4f414e5f4645455f414d4f55815261139560f21b602082015291505b5060400190565b6020808252810161071981612426565b604081016124868285611d18565b610b806020830184611d18565b602281526000602082017f464c4153485f4c4f414e5f4645455f50455243454e544147455f544f4f5f484981526108e960f31b60208201529150612461565b6020808252810161071981612493565b60208082527f494e56414c49445f464c4153485f4c4f414e5f4645455f524543495049454e54910190815260006122d7565b60208082528101610719816124e2565b60158152600060208201740929ca0aaa8be988a9c8ea890be9a92a69a82a8869605b1b815291506122d7565b6020808252810161071981612524565b634e487b7160e01b600052603260045260246000fd5b60208082528101610b80818461231a565b60006125938383612003565b505060200190565b60006125a5825190565b80845260209384019383018060005b838110156125d95781516125c88882612587565b9750602083019250506001016125b4565b509495945050505050565b60006125938383611d18565b60006125fa825190565b80845260209384019383018060005b838110156125d957815161261d88826125e4565b975060208301925050600101612609565b6080808252810161263f818761259b565b9050818103602083015261265381866125f0565b9050818103604083015261266781856125f0565b9050818103606083015261267b818461231a565b9695505050505050565b602681526000602082017f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b60208201529150612461565b6020808252810161071981612685565b601f81526000602082017f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00815291506122d7565b60208082528101610719816126d8565b60208082527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572910190815260006122d7565b602080825281016107198161271c565b601081526000602082016f14185d5cd8589b194e881c185d5cd95960821b815291506122d7565b602080825281016107198161275e565b601481526000602082017314185d5cd8589b194e881b9bdd081c185d5cd95960621b815291506122d7565b6020808252810161071981612795565b6000815b91505090565b6000610719826127d0565b60006127ef825190565b6127fd8185602086016122ee565b9290920192915050565b6000610b8082846127e5565b600081600019048311821515161561282d5761282d61220e565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261285757612857612832565b500490565b604081016124868285612003565b600061ffff8216610719565b611d1a8161286a565b6000808252602082016127d4565b60a0810161289b8287612876565b6128a86020830186612003565b6128b56040830185611d18565b6128c26060830184611d18565b818103608083015261267b8161287f56fea26469706673582212208539bcd7e1382783133f2080efcd30632940d2710efb2f5de93727ff03fcb9f464736f6c634300080f0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f
-----Decoded View---------------
Arg [0] : _wETH (address): 0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$2,102,977.72
Net Worth in ETH
Token Allocations
ETH
41.45%
USDC
30.07%
USDT
14.25%
Others
14.24%
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| LINEA | 24.00% | $2,958.06 | 170.6054 | $504,661.31 | |
| LINEA | 17.64% | $0.999699 | 371,004.1116 | $370,892.44 | |
| LINEA | 9.90% | $0.998504 | 208,572.2606 | $208,260.24 | |
| LINEA | 3.83% | $3,622.33 | 22.2357 | $80,544.9 | |
| LINEA | 1.69% | $3,158.91 | 11.2498 | $35,537.06 | |
| LINEA | 1.30% | $0.995608 | 27,451.7798 | $27,331.21 | |
| LINEA | 0.99% | $0.000003 | 7,572,105,229.9638 | $20,823.29 | |
| LINEA | 0.81% | $89,211 | 0.1912 | $17,055.58 | |
| LINEA | 0.25% | $890.77 | 5.8729 | $5,231.36 | |
| LINEA | 0.14% | $0.999108 | 2,904.8039 | $2,902.21 | |
| LINEA | 0.09% | $0.000397 | 4,508,653.4117 | $1,788.76 | |
| LINEA | 0.08% | $0.127229 | 14,047.2296 | $1,787.21 | |
| LINEA | 0.04% | $12.09 | 71.6027 | $865.68 | |
| LINEA | 0.03% | $0.18395 | 3,847.6381 | $707.77 | |
| LINEA | 0.02% | $3,123.36 | 0.1642 | $512.84 | |
| LINEA | <0.01% | $0.000008 | 12,332,196.5874 | $97.18 | |
| LINEA | <0.01% | $1 | 89.712 | $89.8 | |
| LINEA | <0.01% | $0.000004 | 8,223,487.8933 | $35.61 | |
| LINEA | <0.01% | <$0.000001 | 98,034,789.539 | $30.71 | |
| LINEA | <0.01% | $0.000001 | 16,628,622.8056 | $11.56 | |
| LINEA | <0.01% | $0.044655 | 207.6066 | $9.27 | |
| LINEA | <0.01% | $3,313.54 | 0.00264336 | $8.76 | |
| LINEA | <0.01% | $0.000178 | 37,373.5542 | $6.67 | |
| LINEA | <0.01% | $0.01266 | 416.9507 | $5.28 | |
| LINEA | <0.01% | $0.026831 | 58.7632 | $1.58 | |
| SCROLL | 17.45% | $2,957.82 | 124.0488 | $366,914.42 | |
| SCROLL | 12.43% | $0.999559 | 261,544.9011 | $261,429.56 | |
| SCROLL | 4.34% | $0.99853 | 91,506.3734 | $91,371.87 | |
| SCROLL | 1.95% | $3,622.87 | 11.3243 | $41,026.32 | |
| SCROLL | 1.12% | $89,245.94 | 0.2635 | $23,515.44 | |
| SCROLL | 0.77% | $0.075339 | 214,095.6211 | $16,129.75 | |
| SCROLL | 0.65% | $3,419.49 | 3.9966 | $13,666.5 | |
| SCROLL | 0.43% | $0.999134 | 9,088.0656 | $9,080.2 | |
| SCROLL | 0.03% | $3,212.75 | 0.1913 | $614.74 | |
| SCROLL | <0.01% | $3,581.99 | 0.00254834 | $9.13 | |
| SCROLL | <0.01% | $0.000079 | 21,136.4997 | $1.67 | |
| SCROLL | <0.01% | $3,148.43 | 0.00044562 | $1.4 | |
| ETH | <0.01% | $2,958.06 | 0.0053524 | $15.83 | |
| BSC | <0.01% | $890.89 | 0.00272596 | $2.43 | |
| TAIKO | <0.01% | $0.999869 | 0.1655 | $0.1655 | |
| TAIKO | <0.01% | $2,958.06 | 0.0000054 | $0.015969 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.