More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
19618016 | 260 days ago | 0.06151747 ETH | ||||
19618016 | 260 days ago | 0.06151747 ETH | ||||
19225460 | 315 days ago | 0.023893 ETH | ||||
19225460 | 315 days ago | 0.023893 ETH | ||||
19221395 | 316 days ago | 0.02689468 ETH | ||||
19221395 | 316 days ago | 0.02689468 ETH | ||||
19214252 | 317 days ago | 0.21552406 ETH | ||||
19214252 | 317 days ago | 0.21552406 ETH | ||||
19013412 | 345 days ago | 0.17677402 ETH | ||||
19013412 | 345 days ago | 0.17677402 ETH | ||||
19012014 | 345 days ago | 0.21979017 ETH | ||||
19012014 | 345 days ago | 0.21979017 ETH | ||||
19006236 | 346 days ago | 0.3127826 ETH | ||||
19006236 | 346 days ago | 0.3127826 ETH | ||||
18906564 | 360 days ago | 0.16512716 ETH | ||||
18906564 | 360 days ago | 0.16512716 ETH | ||||
18824660 | 372 days ago | 0.241923 ETH | ||||
18824660 | 372 days ago | 0.241923 ETH | ||||
18766011 | 380 days ago | 0.40408633 ETH | ||||
18766011 | 380 days ago | 0.40408633 ETH | ||||
18708201 | 388 days ago | 0.26337212 ETH | ||||
18708201 | 388 days ago | 0.26337212 ETH | ||||
18663523 | 394 days ago | 0.36387866 ETH | ||||
18663523 | 394 days ago | 0.36387866 ETH | ||||
18604583 | 402 days ago | 0.19227029 ETH |
Loading...
Loading
Contract Name:
EulerRedemptionBridge
Compiler Version
v0.8.18+commit.87f61d96
Optimization Enabled:
Yes with 100000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Apache-2.0 // Copyright 2022 Aztec. pragma solidity >=0.8.4; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import {IERC4626} from "@openzeppelin/contracts/interfaces/IERC4626.sol"; import {IRollupProcessor} from "rollup-encoder/interfaces/IRollupProcessor.sol"; import {AztecTypes} from "rollup-encoder/libraries/AztecTypes.sol"; import {BridgeBase} from "../base/BridgeBase.sol"; import {ErrorLib} from "../base/ErrorLib.sol"; import {IWETH} from "../../interfaces/IWETH.sol"; import {ISwapRouter} from "../../interfaces/uniswapv3/ISwapRouter.sol"; import {IVault, IAsset, PoolSpecialization} from "../../interfaces/element/IVault.sol"; interface IMigrator { function migrate(uint256 _amount, bytes32 _acceptanceToken) external returns (uint256, uint256, uint256); function ERC4626Token() external view returns (address); } contract EulerRedemptionBridge is BridgeBase { using SafeERC20 for IERC20; using SafeERC20 for IERC4626; error SlippageExceeded(); IWETH public constant WETH = IWETH(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); IERC20 public constant DAI = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F); IERC20 public constant USDC = IERC20(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48); IERC20 public constant WSTETH = IERC20(0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0); IERC4626 public constant WEWETH = IERC4626(0x3c66B18F67CA6C1A71F829E2F6a0c987f97462d0); IERC4626 public constant WEDAI = IERC4626(0x4169Df1B7820702f566cc10938DA51F6F597d264); IERC4626 public constant WEWSTETH = IERC4626(0x60897720AA966452e8706e74296B018990aEc527); bytes32 public constant TERMS_AND_CONDITIONS_HASH = 0x427a506ff6e15bd1b7e4e93da52c8ec95f6af1279618a2f076946e83d8294996; ISwapRouter public constant ROUTER = ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564); IVault public constant BALANCER = IVault(0xBA12222222228d8Ba445958a75a0704d566BF2C8); bytes32 public constant BALANCER_WSTETH_POOLID = 0x32296969ef14eb0c6d29669c550d4a0449130230000200000000000000000080; IMigrator public immutable WETH_MIGRATOR; IMigrator public immutable DAI_MIGRATOR; IMigrator public immutable WSTETH_MIGRATOR; constructor(address _rollupProcessor, address _wethMigrator, address _daiMigrator, address _wstethMigrator) BridgeBase(_rollupProcessor) { WETH_MIGRATOR = IMigrator(_wethMigrator); DAI_MIGRATOR = IMigrator(_daiMigrator); WSTETH_MIGRATOR = IMigrator(_wstethMigrator); IERC20(WETH_MIGRATOR.ERC4626Token()).approve(address(WETH_MIGRATOR), type(uint256).max); IERC20(DAI_MIGRATOR.ERC4626Token()).approve(address(DAI_MIGRATOR), type(uint256).max); IERC20(WSTETH_MIGRATOR.ERC4626Token()).approve(address(WSTETH_MIGRATOR), type(uint256).max); WETH.approve(address(BALANCER), type(uint256).max); WETH.approve(address(ROUTER), type(uint256).max); DAI.approve(address(ROUTER), type(uint256).max); USDC.approve(address(ROUTER), type(uint256).max); DAI.approve(address(ROLLUP_PROCESSOR), type(uint256).max); WSTETH.approve(address(ROLLUP_PROCESSOR), type(uint256).max); } receive() external payable {} /** * @notice Redeems shares of Euler ERC4626 vaults for underlying assets * following the redemption scheme. Will take the assets received and swap it into * the expected underlying. * @param _inputAssetA - The input asset to redeem * @param _outputAssetA - The output asset to receive * @param _totalInputValue - The total amount of input asset to redeem * @param _interactionNonce - The nonce of the interaction * @param _auxData - The aux data of the interaction (minAmountPerFullShare) * @return outputValueA - The amount of output asset received */ function convert( AztecTypes.AztecAsset calldata _inputAssetA, AztecTypes.AztecAsset calldata, AztecTypes.AztecAsset calldata _outputAssetA, AztecTypes.AztecAsset calldata, uint256 _totalInputValue, uint256 _interactionNonce, uint64 _auxData, address ) external payable override(BridgeBase) onlyRollup returns (uint256 outputValueA, uint256, bool) { if (_inputAssetA.erc20Address == address(WEWETH)) { return _exitWeweth(_totalInputValue, _outputAssetA.erc20Address, _interactionNonce, _auxData); } else if (_inputAssetA.erc20Address == address(WEDAI)) { return _exitDai(_totalInputValue, _outputAssetA.erc20Address, _auxData); } else if (_inputAssetA.erc20Address == address(WEWSTETH)) { return _exitWsteth(_totalInputValue, _outputAssetA.erc20Address, _auxData); } else { revert ErrorLib.InvalidInputA(); } } /** * @notice Redeems shares of WEWETH vault for weth, dai, usdc * swaps assets to Eth * @param _totalInputValue - The total amount of input asset to redeem * @param _outputAssetA - The output asset to receive * @param _interactionNonce - The nonce of the interaction * @param _auxData - The aux data of the interaction (minAmountPerFullShare) * @return outputValueA - The amount of output asset received */ function _exitWeweth(uint256 _totalInputValue, address _outputAssetA, uint256 _interactionNonce, uint64 _auxData) internal returns (uint256 outputValueA, uint256, bool) { if (_outputAssetA != address(0)) { revert ErrorLib.InvalidOutputA(); } // Migrate the asset. (uint256 wethAmount, uint256 daiAmount, uint256 usdcAmount) = WETH_MIGRATOR.migrate(_totalInputValue, _acceptanceToken()); // Swap dai for usdc on uniswap { if (daiAmount > 0) { bytes memory path = abi.encodePacked(address(DAI), uint24(100), address(USDC)); usdcAmount += ROUTER.exactInput( ISwapRouter.ExactInputParams({ path: path, recipient: address(this), deadline: block.timestamp, amountIn: daiAmount, amountOutMinimum: 0 }) ); } } // Swap usdc to weth { if (usdcAmount > 0) { bytes memory path = abi.encodePacked(address(USDC), uint24(500), address(WETH)); wethAmount += ROUTER.exactInput( ISwapRouter.ExactInputParams({ path: path, recipient: address(this), deadline: block.timestamp, amountIn: usdcAmount, amountOutMinimum: 0 }) ); } } // @todo slippage aux could be 1e16 precision if there are very high interest amounts. uint256 minExpected = _totalInputValue * _auxData / 1e18; if (wethAmount < minExpected) { revert SlippageExceeded(); } IWETH(WETH).withdraw(wethAmount); IRollupProcessor(ROLLUP_PROCESSOR).receiveEthFromBridge{value: wethAmount}(_interactionNonce); return (wethAmount, 0, false); } /** * @notice Redeems shares of WEDAI vault for weth, dai, usdc * swaps assets to Dai * @param _totalInputValue - The total amount of input asset to redeem * @param _outputAssetA - The output asset to receive * @param _auxData - The aux data of the interaction (minAmountPerFullShare) * @return outputValueA - The amount of output asset received */ function _exitDai(uint256 _totalInputValue, address _outputAssetA, uint64 _auxData) internal returns (uint256 outputValueA, uint256, bool) { if (_outputAssetA != address(DAI)) { revert ErrorLib.InvalidOutputA(); } // Migrate the asset. (uint256 wethAmount, uint256 daiAmount, uint256 usdcAmount) = DAI_MIGRATOR.migrate(_totalInputValue, _acceptanceToken()); // Swap weth to usdc { if (wethAmount > 0) { bytes memory path = abi.encodePacked(address(WETH), uint24(500), address(USDC)); usdcAmount += ROUTER.exactInput( ISwapRouter.ExactInputParams({ path: path, recipient: address(this), deadline: block.timestamp, amountIn: wethAmount, amountOutMinimum: 0 }) ); } } // Swap usdc for dai on uniswap { if (usdcAmount > 0) { bytes memory path = abi.encodePacked(address(USDC), uint24(100), address(DAI)); daiAmount += ROUTER.exactInput( ISwapRouter.ExactInputParams({ path: path, recipient: address(this), deadline: block.timestamp, amountIn: usdcAmount, amountOutMinimum: 0 }) ); } } // @todo slippage aux could be 1e16 precision if there are very high interest amounts. uint256 minExpected = _totalInputValue * _auxData / 1e18; if (daiAmount < minExpected) { revert SlippageExceeded(); } return (daiAmount, 0, false); } /** * @notice Redeems shares of WEWESTETH vault for weth, dai, usdc * swaps assets to Wsteth * @param _totalInputValue - The total amount of input asset to redeem * @param _outputAssetA - The output asset to receive * @param _auxData - The aux data of the interaction (minAmountPerFullShare) * @return outputValueA - The amount of output asset received */ function _exitWsteth(uint256 _totalInputValue, address _outputAssetA, uint64 _auxData) internal returns (uint256 outputValueA, uint256, bool) { if (_outputAssetA != address(WSTETH)) { revert ErrorLib.InvalidOutputA(); } // Migrate the asset. (uint256 wethAmount, uint256 daiAmount, uint256 usdcAmount) = WSTETH_MIGRATOR.migrate(_totalInputValue, _acceptanceToken()); // Swap dai for usdc on uniswap { if (daiAmount > 0) { bytes memory path = abi.encodePacked(address(DAI), uint24(100), address(USDC)); usdcAmount += ROUTER.exactInput( ISwapRouter.ExactInputParams({ path: path, recipient: address(this), deadline: block.timestamp, amountIn: daiAmount, amountOutMinimum: 0 }) ); } } // Swap usdc to weth { if (usdcAmount > 0) { bytes memory path = abi.encodePacked(address(USDC), uint24(500), address(WETH)); wethAmount += ROUTER.exactInput( ISwapRouter.ExactInputParams({ path: path, recipient: address(this), deadline: block.timestamp, amountIn: usdcAmount, amountOutMinimum: 0 }) ); } } // Swap weth to wsteth uint256 wstethBal; { if (wethAmount > 0) { IVault.SingleSwap memory singleSwap = IVault.SingleSwap({ poolId: BALANCER_WSTETH_POOLID, kind: IVault.SwapKind.GIVEN_IN, assetIn: IAsset(address(WETH)), assetOut: IAsset(address(WSTETH)), amount: wethAmount, userData: "0x00" }); IVault.FundManagement memory fundManagement = IVault.FundManagement({ sender: address(this), fromInternalBalance: false, recipient: payable(address(this)), toInternalBalance: false }); wstethBal = BALANCER.swap(singleSwap, fundManagement, 0, block.timestamp); } } // @todo slippage aux could be 1e16 precision if there are very high interest amounts. uint256 minExpected = _totalInputValue * _auxData / 1e18; if (wstethBal < minExpected) { revert SlippageExceeded(); } return (wstethBal, 0, false); } /** * @notice Computes the acceptance token for the migration. * @return The acceptance token. */ function _acceptanceToken() internal view returns (bytes32) { return keccak256(abi.encodePacked(address(this), TERMS_AND_CONDITIONS_HASH)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (interfaces/IERC4626.sol) pragma solidity ^0.8.0; import "../token/ERC20/IERC20.sol"; import "../token/ERC20/extensions/IERC20Metadata.sol"; /** * @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626]. * * _Available since v4.7._ */ interface IERC4626 is IERC20, IERC20Metadata { event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); event Withdraw( address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares ); /** * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. * * - MUST be an ERC-20 token contract. * - MUST NOT revert. */ function asset() external view returns (address assetTokenAddress); /** * @dev Returns the total amount of the underlying asset that is “managed” by Vault. * * - SHOULD include any compounding that occurs from yield. * - MUST be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT revert. */ function totalAssets() external view returns (uint256 totalManagedAssets); /** * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToShares(uint256 assets) external view returns (uint256 shares); /** * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToAssets(uint256 shares) external view returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, * through a deposit call. * * - MUST return a limited value if receiver is subject to some deposit limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. * - MUST NOT revert. */ function maxDeposit(address receiver) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given * current on-chain conditions. * * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit * call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called * in the same transaction. * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the * deposit would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewDeposit(uint256 assets) external view returns (uint256 shares); /** * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * deposit execution, and are accounted for during deposit. * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function deposit(uint256 assets, address receiver) external returns (uint256 shares); /** * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. * - MUST return a limited value if receiver is subject to some mint limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. * - MUST NOT revert. */ function maxMint(address receiver) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given * current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call * in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the * same transaction. * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint * would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by minting. */ function previewMint(uint256 shares) external view returns (uint256 assets); /** * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint * execution, and are accounted for during mint. * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function mint(uint256 shares, address receiver) external returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the * Vault, through a withdraw call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST NOT revert. */ function maxWithdraw(address owner) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, * given current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw * call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if * called * in the same transaction. * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though * the withdrawal would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewWithdraw(uint256 assets) external view returns (uint256 shares); /** * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * withdraw execution, and are accounted for during withdraw. * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function withdraw( uint256 assets, address receiver, address owner ) external returns (uint256 shares); /** * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, * through a redeem call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. * - MUST NOT revert. */ function maxRedeem(address owner) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, * given current on-chain conditions. * * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call * in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the * same transaction. * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the * redemption would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by redeeming. */ function previewRedeem(uint256 shares) external view returns (uint256 assets); /** * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * redeem execution, and are accounted for during redeem. * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function redeem( uint256 shares, address receiver, address owner ) external returns (uint256 assets); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: Apache-2.0 // Copyright 2022 Aztec pragma solidity >=0.8.4; // @dev For documentation of the functions within this interface see RollupProcessor contract interface IRollupProcessor { /*---------------------------------------- MUTATING FUNCTIONS ----------------------------------------*/ function pause() external; function unpause() external; function setRollupProvider(address _provider, bool _valid) external; function setVerifier(address _verifier) external; function setAllowThirdPartyContracts(bool _allowThirdPartyContracts) external; function setDefiBridgeProxy(address _defiBridgeProxy) external; function setSupportedAsset(address _token, uint256 _gasLimit) external; function setSupportedBridge(address _bridge, uint256 _gasLimit) external; function processRollup(bytes calldata _encodedProofData, bytes calldata _signatures) external; function receiveEthFromBridge(uint256 _interactionNonce) external payable; function approveProof(bytes32 _proofHash) external; function depositPendingFunds(uint256 _assetId, uint256 _amount, address _owner, bytes32 _proofHash) external payable; function offchainData(uint256 _rollupId, uint256 _chunk, uint256 _totalChunks, bytes calldata _offchainTxData) external; function processAsyncDefiInteraction(uint256 _interactionNonce) external returns (bool); /*---------------------------------------- NON-MUTATING FUNCTIONS ----------------------------------------*/ function rollupStateHash() external view returns (bytes32); function userPendingDeposits(uint256 _assetId, address _user) external view returns (uint256); function defiBridgeProxy() external view returns (address); function prevDefiInteractionsHash() external view returns (bytes32); function paused() external view returns (bool); function verifier() external view returns (address); function getDataSize() external view returns (uint256); function getPendingDefiInteractionHashesLength() external view returns (uint256); function getDefiInteractionHashesLength() external view returns (uint256); function getAsyncDefiInteractionHashesLength() external view returns (uint256); function getSupportedBridge(uint256 _bridgeAddressId) external view returns (address); function getSupportedBridgesLength() external view returns (uint256); function getSupportedAssetsLength() external view returns (uint256); function getSupportedAsset(uint256 _assetId) external view returns (address); function getEscapeHatchStatus() external view returns (bool, uint256); function assetGasLimits(uint256 _bridgeAddressId) external view returns (uint256); function bridgeGasLimits(uint256 _bridgeAddressId) external view returns (uint256); function allowThirdPartyContracts() external view returns (bool); }
// SPDX-License-Identifier: Apache-2.0 // Copyright 2022 Aztec pragma solidity >=0.8.4; library AztecTypes { enum AztecAssetType { NOT_USED, ETH, ERC20, VIRTUAL } struct AztecAsset { uint256 id; address erc20Address; AztecAssetType assetType; } }
// SPDX-License-Identifier: Apache-2.0 // Copyright 2022 Aztec pragma solidity >=0.8.4; import {AztecTypes} from "rollup-encoder/libraries/AztecTypes.sol"; interface IDefiBridge { /** * @notice A function which converts input assets to output assets. * @param _inputAssetA A struct detailing the first input asset * @param _inputAssetB A struct detailing the second input asset * @param _outputAssetA A struct detailing the first output asset * @param _outputAssetB A struct detailing the second output asset * @param _totalInputValue An amount of input assets transferred to the bridge (Note: "total" is in the name * because the value can represent summed/aggregated token amounts of users actions on L2) * @param _interactionNonce A globally unique identifier of this interaction/`convert(...)` call. * @param _auxData Bridge specific data to be passed into the bridge contract (e.g. slippage, nftID etc.) * @return outputValueA An amount of `_outputAssetA` returned from this interaction. * @return outputValueB An amount of `_outputAssetB` returned from this interaction. * @return isAsync A flag indicating if the interaction is async. * @dev This function is called from the RollupProcessor contract via the DefiBridgeProxy. Before this function is * called _RollupProcessor_ contract will have sent you all the assets defined by the input params. This * function is expected to convert input assets to output assets (e.g. on Uniswap) and return the amounts * of output assets to be received by the _RollupProcessor_. If output assets are ERC20 tokens the bridge has * to _RollupProcessor_ as a spender before the interaction is finished. If some of the output assets is ETH * it has to be sent to _RollupProcessor_ via the `receiveEthFromBridge(uint256 _interactionNonce)` method * inside before the `convert(...)` function call finishes. * @dev If there are two input assets, equal amounts of both assets will be transferred to the bridge before this * method is called. * @dev **BOTH** output assets could be virtual but since their `assetId` is currently assigned as * `_interactionNonce` it would simply mean that more of the same virtual asset is minted. * @dev If this interaction is async the function has to return `(0,0 true)`. Async interaction will be finalised at * a later time and its output assets will be returned in a `IDefiBridge.finalise(...)` call. * */ function convert( AztecTypes.AztecAsset calldata _inputAssetA, AztecTypes.AztecAsset calldata _inputAssetB, AztecTypes.AztecAsset calldata _outputAssetA, AztecTypes.AztecAsset calldata _outputAssetB, uint256 _totalInputValue, uint256 _interactionNonce, uint64 _auxData, address _rollupBeneficiary ) external payable returns (uint256 outputValueA, uint256 outputValueB, bool isAsync); /** * @notice A function that finalises asynchronous interaction. * @param _inputAssetA A struct detailing the first input asset * @param _inputAssetB A struct detailing the second input asset * @param _outputAssetA A struct detailing the first output asset * @param _outputAssetB A struct detailing the second output asset * @param _interactionNonce A globally unique identifier of this interaction/`convert(...)` call. * @param _auxData Bridge specific data to be passed into the bridge contract (e.g. slippage, nftID etc.) * @return outputValueA An amount of `_outputAssetA` returned from this interaction. * @return outputValueB An amount of `_outputAssetB` returned from this interaction. * @dev This function should use the `BridgeBase.onlyRollup()` modifier to ensure it can only be called from * the `RollupProcessor.processAsyncDefiInteraction(uint256 _interactionNonce)` method. * */ function finalise( AztecTypes.AztecAsset calldata _inputAssetA, AztecTypes.AztecAsset calldata _inputAssetB, AztecTypes.AztecAsset calldata _outputAssetA, AztecTypes.AztecAsset calldata _outputAssetB, uint256 _interactionNonce, uint64 _auxData ) external payable returns (uint256 outputValueA, uint256 outputValueB, bool interactionComplete); }
// SPDX-License-Identifier: Apache-2.0 // Copyright 2022 Aztec pragma solidity >=0.8.4; // @dev documentation of this interface is in its implementation (Subsidy contract) interface ISubsidy { /** * @notice Container for Subsidy related information * @member available Amount of ETH remaining to be paid out * @member gasUsage Amount of gas the interaction consumes (used to define max possible payout) * @member minGasPerMinute Minimum amount of gas per minute the subsidizer has to subsidize * @member gasPerMinute Amount of gas per minute the subsidizer is willing to subsidize * @member lastUpdated Last time subsidy was paid out or funded (if not subsidy was yet claimed after funding) */ struct Subsidy { uint128 available; uint32 gasUsage; uint32 minGasPerMinute; uint32 gasPerMinute; uint32 lastUpdated; } function setGasUsageAndMinGasPerMinute(uint256 _criteria, uint32 _gasUsage, uint32 _minGasPerMinute) external; function setGasUsageAndMinGasPerMinute( uint256[] calldata _criteria, uint32[] calldata _gasUsage, uint32[] calldata _minGasPerMinute ) external; function registerBeneficiary(address _beneficiary) external; function subsidize(address _bridge, uint256 _criteria, uint32 _gasPerMinute) external payable; function topUp(address _bridge, uint256 _criteria) external payable; function claimSubsidy(uint256 _criteria, address _beneficiary) external returns (uint256); function withdraw(address _beneficiary) external returns (uint256); // solhint-disable-next-line function MIN_SUBSIDY_VALUE() external view returns (uint256); function claimableAmount(address _beneficiary) external view returns (uint256); function isRegistered(address _beneficiary) external view returns (bool); function getSubsidy(address _bridge, uint256 _criteria) external view returns (Subsidy memory); function getAccumulatedSubsidyAmount(address _bridge, uint256 _criteria) external view returns (uint256); }
// SPDX-License-Identifier: Apache-2.0 // Copyright 2022 Aztec. pragma solidity >=0.8.4; import {IDefiBridge} from "../../aztec/interfaces/IDefiBridge.sol"; import {ISubsidy} from "../../aztec/interfaces/ISubsidy.sol"; import {AztecTypes} from "rollup-encoder/libraries/AztecTypes.sol"; import {ErrorLib} from "./ErrorLib.sol"; /** * @title BridgeBase * @notice A base that bridges can be built upon which imports a limited set of features * @dev Reverts `convert` with missing implementation, and `finalise` with async disabled * @author Lasse Herskind */ abstract contract BridgeBase is IDefiBridge { error MissingImplementation(); ISubsidy public constant SUBSIDY = ISubsidy(0xABc30E831B5Cc173A9Ed5941714A7845c909e7fA); address public immutable ROLLUP_PROCESSOR; constructor(address _rollupProcessor) { ROLLUP_PROCESSOR = _rollupProcessor; } modifier onlyRollup() { if (msg.sender != ROLLUP_PROCESSOR) { revert ErrorLib.InvalidCaller(); } _; } function convert( AztecTypes.AztecAsset calldata, AztecTypes.AztecAsset calldata, AztecTypes.AztecAsset calldata, AztecTypes.AztecAsset calldata, uint256, uint256, uint64, address ) external payable virtual override(IDefiBridge) returns (uint256, uint256, bool) { revert MissingImplementation(); } function finalise( AztecTypes.AztecAsset calldata, AztecTypes.AztecAsset calldata, AztecTypes.AztecAsset calldata, AztecTypes.AztecAsset calldata, uint256, uint64 ) external payable virtual override(IDefiBridge) returns (uint256, uint256, bool) { revert ErrorLib.AsyncDisabled(); } /** * @notice Computes the criteria that is passed on to the subsidy contract when claiming * @dev Should be overridden by bridge implementation if intended to limit subsidy. * @return The criteria to be passed along */ function computeCriteria( AztecTypes.AztecAsset calldata, AztecTypes.AztecAsset calldata, AztecTypes.AztecAsset calldata, AztecTypes.AztecAsset calldata, uint64 ) public view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: Apache-2.0 // Copyright 2022 Aztec. pragma solidity >=0.8.4; library ErrorLib { error InvalidCaller(); error InvalidInput(); error InvalidInputA(); error InvalidInputB(); error InvalidOutputA(); error InvalidOutputB(); error InvalidInputAmount(); error InvalidAuxData(); error ApproveFailed(address token); error TransferFailed(address token); error InvalidNonce(); error AsyncDisabled(); }
// SPDX-License-Identifier: Apache-2.0 // Copyright 2022 Aztec. pragma solidity >=0.8.4; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface IWETH is IERC20 { function deposit() external payable; function withdraw(uint256 amount) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.4; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface IAsset { // solhint-disable-previous-line no-empty-blocks } enum PoolSpecialization { GENERAL, MINIMAL_SWAP_INFO, TWO_TOKEN } interface IVault { enum SwapKind { GIVEN_IN, GIVEN_OUT } /** * @dev Performs a swap with a single Pool. * * If the swap is 'given in' (the number of tokens to send to the Pool is known), it returns the amount of tokens * taken from the Pool, which must be greater than or equal to `limit`. * * If the swap is 'given out' (the number of tokens to take from the Pool is known), it returns the amount of tokens * sent to the Pool, which must be less than or equal to `limit`. * * Internal Balance usage and the recipient are determined by the `funds` struct. * * Emits a `Swap` event. */ function swap(SingleSwap memory singleSwap, FundManagement memory funds, uint256 limit, uint256 deadline) external payable returns (uint256); /** * @dev Data for a single swap executed by `swap`. `amount` is either `amountIn` or `amountOut` depending on * the `kind` value. * * `assetIn` and `assetOut` are either token addresses, or the IAsset sentinel value for ETH (the zero address). * Note that Pools never interact with ETH directly: it will be wrapped to or unwrapped from WETH by the Vault. * * The `userData` field is ignored by the Vault, but forwarded to the Pool in the `onSwap` hook, and may be * used to extend swap behavior. */ struct SingleSwap { bytes32 poolId; SwapKind kind; IAsset assetIn; IAsset assetOut; uint256 amount; bytes userData; } /** * @dev All tokens in a swap are either sent from the `sender` account to the Vault, or from the Vault to the * `recipient` account. * * If the caller is not `sender`, it must be an authorized relayer for them. * * If `fromInternalBalance` is true, the `sender`'s Internal Balance will be preferred, performing an ERC20 * transfer for the difference between the requested amount and the User's Internal Balance (if any). The `sender` * must have allowed the Vault to use their tokens via `IERC20.approve()`. This matches the behavior of * `joinPool`. * * If `toInternalBalance` is true, tokens will be deposited to `recipient`'s internal balance instead of * transferred. This matches the behavior of `exitPool`. * * Note that ETH cannot be deposited to or withdrawn from Internal Balance: attempting to do so will trigger a * revert. */ struct FundManagement { address sender; bool fromInternalBalance; address payable recipient; bool toInternalBalance; } // will revert if poolId is not a registered pool function getPool(bytes32 poolId) external view returns (address, PoolSpecialization); /** * @dev Simulates a call to `batchSwap`, returning an array of Vault asset deltas. Calls to `swap` cannot be * simulated directly, but an equivalent `batchSwap` call can and will yield the exact same result. * * Each element in the array corresponds to the asset at the same index, and indicates the number of tokens (or ETH) * the Vault would take from the sender (if positive) or send to the recipient (if negative). The arguments it * receives are the same that an equivalent `batchSwap` call would receive. * * Unlike `batchSwap`, this function performs no checks on the sender or recipient field in the `funds` struct. * This makes it suitable to be called by off-chain applications via eth_call without needing to hold tokens, * approve them for the Vault, or even know a user's address. * * Note that this function is not 'view' (due to implementation details): the client code must explicitly execute * eth_call instead of eth_sendTransaction. */ struct BatchSwapStep { bytes32 poolId; uint256 assetInIndex; uint256 assetOutIndex; uint256 amount; bytes userData; } function queryBatchSwap( SwapKind kind, BatchSwapStep[] memory swaps, IAsset[] memory assets, FundManagement memory funds ) external view returns (int256[] memory assetDeltas); /** * @dev Returns a Pool's registered tokens, the total balance for each, and the latest block when *any* of * the tokens' `balances` changed. * * The order of the `tokens` array is the same order that will be used in `joinPool`, `exitPool`, as well as in all * Pool hooks (where applicable). Calls to `registerTokens` and `deregisterTokens` may change this order. * * If a Pool only registers tokens once, and these are sorted in ascending order, they will be stored in the same * order as passed to `registerTokens`. * * Total balances include both tokens held by the Vault and those withdrawn by the Pool's Asset Managers. These are * the amounts used by joins, exits and swaps. For a detailed breakdown of token balances, use `getPoolTokenInfo` * instead. */ function getPoolTokens(bytes32 poolId) external view returns (IERC20[] memory tokens, uint256[] memory balances, uint256 lastChangeBlock); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.4; /// @title Router token swapping functionality /// @notice Functions for swapping tokens via Uniswap V3 interface ISwapRouter { struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; } /// @notice Swaps `amountIn` of one token for as much as possible of another token /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata /// @return amountOut The amount of the received token function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); struct ExactInputParams { bytes path; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; } /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata /// @return amountOut The amount of the received token function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut); struct ExactOutputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; uint160 sqrtPriceLimitX96; } /// @notice Swaps as little as possible of one token for `amountOut` of another token /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata /// @return amountIn The amount of the input token function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn); struct ExactOutputParams { bytes path; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; } /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed) /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata /// @return amountIn The amount of the input token function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn); }
{ "remappings": [ "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "ds-test/=lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "euler-4626-redemption/=lib/euler-4626-redemption/src/", "euler-redemption/=lib/euler-4626-redemption/src/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "oz/=lib/euler-4626-redemption/lib/openzeppelin-contracts/contracts/", "rollup-encoder/=lib/rollup-encoder/src/", "safe-contracts/=lib/euler-4626-redemption/lib/safe-contracts/contracts/", "safe/=lib/euler-4626-redemption/lib/safe-contracts/contracts/", "solmate/=lib/solmate/src/" ], "optimizer": { "enabled": true, "runs": 100000 }, "metadata": { "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_rollupProcessor","type":"address"},{"internalType":"address","name":"_wethMigrator","type":"address"},{"internalType":"address","name":"_daiMigrator","type":"address"},{"internalType":"address","name":"_wstethMigrator","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AsyncDisabled","type":"error"},{"inputs":[],"name":"InvalidCaller","type":"error"},{"inputs":[],"name":"InvalidInputA","type":"error"},{"inputs":[],"name":"InvalidOutputA","type":"error"},{"inputs":[],"name":"MissingImplementation","type":"error"},{"inputs":[],"name":"SlippageExceeded","type":"error"},{"inputs":[],"name":"BALANCER","outputs":[{"internalType":"contract IVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BALANCER_WSTETH_POOLID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DAI","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DAI_MIGRATOR","outputs":[{"internalType":"contract IMigrator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROLLUP_PROCESSOR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROUTER","outputs":[{"internalType":"contract ISwapRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SUBSIDY","outputs":[{"internalType":"contract ISubsidy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TERMS_AND_CONDITIONS_HASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USDC","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WEDAI","outputs":[{"internalType":"contract IERC4626","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH_MIGRATOR","outputs":[{"internalType":"contract IMigrator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WEWETH","outputs":[{"internalType":"contract IERC4626","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WEWSTETH","outputs":[{"internalType":"contract IERC4626","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WSTETH","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WSTETH_MIGRATOR","outputs":[{"internalType":"contract IMigrator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"enum AztecTypes.AztecAssetType","name":"assetType","type":"uint8"}],"internalType":"struct AztecTypes.AztecAsset","name":"","type":"tuple"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"enum AztecTypes.AztecAssetType","name":"assetType","type":"uint8"}],"internalType":"struct AztecTypes.AztecAsset","name":"","type":"tuple"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"enum AztecTypes.AztecAssetType","name":"assetType","type":"uint8"}],"internalType":"struct AztecTypes.AztecAsset","name":"","type":"tuple"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"enum AztecTypes.AztecAssetType","name":"assetType","type":"uint8"}],"internalType":"struct AztecTypes.AztecAsset","name":"","type":"tuple"},{"internalType":"uint64","name":"","type":"uint64"}],"name":"computeCriteria","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"enum AztecTypes.AztecAssetType","name":"assetType","type":"uint8"}],"internalType":"struct AztecTypes.AztecAsset","name":"_inputAssetA","type":"tuple"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"enum AztecTypes.AztecAssetType","name":"assetType","type":"uint8"}],"internalType":"struct AztecTypes.AztecAsset","name":"","type":"tuple"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"enum AztecTypes.AztecAssetType","name":"assetType","type":"uint8"}],"internalType":"struct AztecTypes.AztecAsset","name":"_outputAssetA","type":"tuple"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"enum AztecTypes.AztecAssetType","name":"assetType","type":"uint8"}],"internalType":"struct AztecTypes.AztecAsset","name":"","type":"tuple"},{"internalType":"uint256","name":"_totalInputValue","type":"uint256"},{"internalType":"uint256","name":"_interactionNonce","type":"uint256"},{"internalType":"uint64","name":"_auxData","type":"uint64"},{"internalType":"address","name":"","type":"address"}],"name":"convert","outputs":[{"internalType":"uint256","name":"outputValueA","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"enum AztecTypes.AztecAssetType","name":"assetType","type":"uint8"}],"internalType":"struct AztecTypes.AztecAsset","name":"","type":"tuple"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"enum AztecTypes.AztecAssetType","name":"assetType","type":"uint8"}],"internalType":"struct AztecTypes.AztecAsset","name":"","type":"tuple"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"enum AztecTypes.AztecAssetType","name":"assetType","type":"uint8"}],"internalType":"struct AztecTypes.AztecAsset","name":"","type":"tuple"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"enum AztecTypes.AztecAssetType","name":"assetType","type":"uint8"}],"internalType":"struct AztecTypes.AztecAsset","name":"","type":"tuple"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint64","name":"","type":"uint64"}],"name":"finalise","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6101006040523480156200001257600080fd5b50604051620024b5380380620024b583398101604081905262000035916200068f565b6001600160a01b0380851660805283811660a081905283821660c05290821660e05260408051633498190560e01b815290516334981905916004808201926020929091908290030181865afa15801562000093573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000b99190620006ec565b60a05160405163095ea7b360e01b81526001600160a01b039182166004820152600019602482015291169063095ea7b3906044016020604051808303816000875af11580156200010d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000133919062000711565b5060c0516001600160a01b031663349819056040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000175573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200019b9190620006ec565b60c05160405163095ea7b360e01b81526001600160a01b039182166004820152600019602482015291169063095ea7b3906044016020604051808303816000875af1158015620001ef573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000215919062000711565b5060e0516001600160a01b031663349819056040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000257573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200027d9190620006ec565b60e05160405163095ea7b360e01b81526001600160a01b039182166004820152600019602482015291169063095ea7b3906044016020604051808303816000875af1158015620002d1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f7919062000711565b5060405163095ea7b360e01b815273ba12222222228d8ba445958a75a0704d566bf2c86004820152600019602482015273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29063095ea7b3906044016020604051808303816000875af115801562000366573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200038c919062000711565b5060405163095ea7b360e01b815273e592427a0aece92de3edee1f18e0157c058615646004820152600019602482015273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29063095ea7b3906044016020604051808303816000875af1158015620003fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000421919062000711565b5060405163095ea7b360e01b815273e592427a0aece92de3edee1f18e0157c0586156460048201526000196024820152736b175474e89094c44da98b954eedeac495271d0f9063095ea7b3906044016020604051808303816000875af115801562000490573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004b6919062000711565b5060405163095ea7b360e01b815273e592427a0aece92de3edee1f18e0157c058615646004820152600019602482015273a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489063095ea7b3906044016020604051808303816000875af115801562000525573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200054b919062000711565b5060805160405163095ea7b360e01b81526001600160a01b0390911660048201526000196024820152736b175474e89094c44da98b954eedeac495271d0f9063095ea7b3906044016020604051808303816000875af1158015620005b3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620005d9919062000711565b5060805160405163095ea7b360e01b81526001600160a01b0390911660048201526000196024820152737f39c581f595b53c5cb19bd0b3f8da6c935e2ca09063095ea7b3906044016020604051808303816000875af115801562000641573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000667919062000711565b505050505062000735565b80516001600160a01b03811681146200068a57600080fd5b919050565b60008060008060808587031215620006a657600080fd5b620006b18562000672565b9350620006c16020860162000672565b9250620006d16040860162000672565b9150620006e16060860162000672565b905092959194509250565b600060208284031215620006ff57600080fd5b6200070a8262000672565b9392505050565b6000602082840312156200072457600080fd5b815180151581146200070a57600080fd5b60805160a05160c05160e051611d2362000792600039600081816102e9015261123301526000818161019b0152610d37015260008181610467015261071a01526000818161036d015281816104d90152610c400152611d236000f3fe6080604052600436106101485760003560e01c8063ad5c4648116100c0578063d9fb643a11610074578063e0bab4c411610059578063e0bab4c41461042d578063e2d51a7714610455578063f8e19cb11461048957600080fd5b8063d9fb643a146103df578063dbeacd541461040757600080fd5b8063ae9467b5116100a5578063ae9467b51461035b578063aedfdaea1461038f578063bb935cbf146103b757600080fd5b8063ad5c46481461030b578063ae4175b71461033357600080fd5b806389a302711161011757806396f50b2d116100fc57806396f50b2d1461029c5780639b07d342146102c4578063a5907215146102d757600080fd5b806389a302711461023257806394d0a7431461025a57600080fd5b806326c3b515146101545780632aa6584a1461018957806332fe7b26146101e25780636508156e1461020a57600080fd5b3661014f57005b600080fd5b61016761016236600461188d565b6104bd565b6040805193845260208401929092521515908201526060015b60405180910390f35b34801561019557600080fd5b506101bd7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610180565b3480156101ee57600080fd5b506101bd73e592427a0aece92de3edee1f18e0157c0586156481565b34801561021657600080fd5b506101bd73abc30e831b5cc173a9ed5941714a7845c909e7fa81565b34801561023e57600080fd5b506101bd73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b34801561026657600080fd5b5061028e7f427a506ff6e15bd1b7e4e93da52c8ec95f6af1279618a2f076946e83d829499681565b604051908152602001610180565b3480156102a857600080fd5b506101bd73ba12222222228d8ba445958a75a0704d566bf2c881565b6101676102d236600461191f565b61068a565b3480156102e357600080fd5b506101bd7f000000000000000000000000000000000000000000000000000000000000000081565b34801561031757600080fd5b506101bd73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b34801561033f57600080fd5b506101bd734169df1b7820702f566cc10938da51f6f597d26481565b34801561036757600080fd5b506101bd7f000000000000000000000000000000000000000000000000000000000000000081565b34801561039b57600080fd5b506101bd733c66b18f67ca6c1a71f829e2f6a0c987f97462d081565b3480156103c357600080fd5b506101bd7360897720aa966452e8706e74296b018990aec52781565b3480156103eb57600080fd5b506101bd737f39c581f595b53c5cb19bd0b3f8da6c935e2ca081565b34801561041357600080fd5b5061028e610422366004611994565b600095945050505050565b34801561043957600080fd5b506101bd736b175474e89094c44da98b954eedeac495271d0f81565b34801561046157600080fd5b506101bd7f000000000000000000000000000000000000000000000000000000000000000081565b34801561049557600080fd5b5061028e7f32296969ef14eb0c6d29669c550d4a044913023000020000000000000000008081565b600080803373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610530576040517f48f5c3ed00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b733c66b18f67ca6c1a71f829e2f6a0c987f97462d061055560408d0160208e01611a00565b73ffffffffffffffffffffffffffffffffffffffff16036105965761058b8761058460408c0160208d01611a00565b88886106c1565b92509250925061067c565b734169df1b7820702f566cc10938da51f6f597d2646105bb60408d0160208e01611a00565b73ffffffffffffffffffffffffffffffffffffffff16036105f05761058b876105ea60408c0160208d01611a00565b87610cc9565b7360897720aa966452e8706e74296b018990aec52761061560408d0160208e01611a00565b73ffffffffffffffffffffffffffffffffffffffff160361064a5761058b8761064460408c0160208d01611a00565b876111c5565b6040517fc582880b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b985098509895505050505050565b60008060006040517f26d18eab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808073ffffffffffffffffffffffffffffffffffffffff861615610713576040517f6c98dcaf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16638277908b8b6107cd6040517fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660208201527f427a506ff6e15bd1b7e4e93da52c8ec95f6af1279618a2f076946e83d8294996603482015260009060540160405160208183030381529060405280519060200120905090565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b168152600481019290925260248201526044016060604051808303816000875af1158015610828573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084c9190611a22565b9194509250905081156109c1576040517f6b175474e89094c44da98b954eedeac495271d0f00000000000000000000000060208201527d64000000000000000000000000000000000000000000000000000000000060348201527fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006037820152600090604b01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815260a0830182528083523060208401524283830152606083018690526000608084015290517fc04b8d5900000000000000000000000000000000000000000000000000000000815290925073e592427a0aece92de3edee1f18e0157c058615649163c04b8d59916109709190600401611ab4565b6020604051808303816000875af115801561098f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b39190611b1a565b6109bd9083611b62565b9150505b8015610b30576040517fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000060208201527e01f4000000000000000000000000000000000000000000000000000000000060348201527fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006037820152600090604b01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815260a0830182528083523060208401524283830152606083018590526000608084015290517fc04b8d5900000000000000000000000000000000000000000000000000000000815290925073e592427a0aece92de3edee1f18e0157c058615649163c04b8d5991610adf9190600401611ab4565b6020604051808303816000875af1158015610afe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b229190611b1a565b610b2c9085611b62565b9350505b6000670de0b6b3a7640000610b4f67ffffffffffffffff8a168d611b7b565b610b599190611b92565b905080841015610b95576040517f8199f5f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810185905273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d90602401600060405180830381600087803b158015610bfb57600080fd5b505af1158015610c0f573d6000803e3d6000fd5b50506040517f12a53623000000000000000000000000000000000000000000000000000000008152600481018c90527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1692506312a53623915086906024016000604051808303818588803b158015610c9c57600080fd5b505af1158015610cb0573d6000803e3d6000fd5b50969e60009e508e9d509b505050505050505050505050565b6000808073ffffffffffffffffffffffffffffffffffffffff8516736b175474e89094c44da98b954eedeac495271d0f14610d30576040517f6c98dcaf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16638277908b8a610dea6040517fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660208201527f427a506ff6e15bd1b7e4e93da52c8ec95f6af1279618a2f076946e83d8294996603482015260009060540160405160208183030381529060405280519060200120905090565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b168152600481019290925260248201526044016060604051808303816000875af1158015610e45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e699190611a22565b919450925090508215610fdf576040517fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000060208201527e01f4000000000000000000000000000000000000000000000000000000000060348201527fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006037820152600090604b01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815260a0830182528083523060208401524283830152606083018790526000608084015290517fc04b8d5900000000000000000000000000000000000000000000000000000000815290925073e592427a0aece92de3edee1f18e0157c058615649163c04b8d5991610f8e9190600401611ab4565b6020604051808303816000875af1158015610fad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd19190611b1a565b610fdb9083611b62565b9150505b801561114d576040517fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000060208201527d64000000000000000000000000000000000000000000000000000000000060348201527f6b175474e89094c44da98b954eedeac495271d0f0000000000000000000000006037820152600090604b01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815260a0830182528083523060208401524283830152606083018590526000608084015290517fc04b8d5900000000000000000000000000000000000000000000000000000000815290925073e592427a0aece92de3edee1f18e0157c058615649163c04b8d59916110fc9190600401611ab4565b6020604051808303816000875af115801561111b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061113f9190611b1a565b6111499084611b62565b9250505b6000670de0b6b3a764000061116c67ffffffffffffffff8a168c611b7b565b6111769190611b92565b9050808310156111b2576040517f8199f5f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5090986000985088975095505050505050565b6000808073ffffffffffffffffffffffffffffffffffffffff8516737f39c581f595b53c5cb19bd0b3f8da6c935e2ca01461122c576040517f6c98dcaf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16638277908b8a6112e66040517fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660208201527f427a506ff6e15bd1b7e4e93da52c8ec95f6af1279618a2f076946e83d8294996603482015260009060540160405160208183030381529060405280519060200120905090565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b168152600481019290925260248201526044016060604051808303816000875af1158015611341573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113659190611a22565b9194509250905081156114da576040517f6b175474e89094c44da98b954eedeac495271d0f00000000000000000000000060208201527d64000000000000000000000000000000000000000000000000000000000060348201527fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006037820152600090604b01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815260a0830182528083523060208401524283830152606083018690526000608084015290517fc04b8d5900000000000000000000000000000000000000000000000000000000815290925073e592427a0aece92de3edee1f18e0157c058615649163c04b8d59916114899190600401611ab4565b6020604051808303816000875af11580156114a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114cc9190611b1a565b6114d69083611b62565b9150505b8015611649576040517fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000060208201527e01f4000000000000000000000000000000000000000000000000000000000060348201527fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006037820152600090604b01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815260a0830182528083523060208401524283830152606083018590526000608084015290517fc04b8d5900000000000000000000000000000000000000000000000000000000815290925073e592427a0aece92de3edee1f18e0157c058615649163c04b8d59916115f89190600401611ab4565b6020604051808303816000875af1158015611617573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163b9190611b1a565b6116459085611b62565b9350505b600083156117bc576040805160c0810182527f32296969ef14eb0c6d29669c550d4a044913023000020000000000000000008081526000602080830182905273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc283850152737f39c581f595b53c5cb19bd0b3f8da6c935e2ca060608085019190915260808085018a90528551808701875260048082527f30783030000000000000000000000000000000000000000000000000000000008286015260a087019190915286519182018752308083529382018590528187019390935290810183905293517f52bbbe2900000000000000000000000000000000000000000000000000000000815292939273ba12222222228d8ba445958a75a0704d566bf2c8926352bbbe299261177492879287929091429101611bcd565b6020604051808303816000875af1158015611793573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b79190611b1a565b925050505b6000670de0b6b3a76400006117db67ffffffffffffffff8b168d611b7b565b6117e59190611b92565b905080821015611821576040517f8199f5f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5099600099508998509650505050505050565b60006060828403121561184657600080fd5b50919050565b803567ffffffffffffffff8116811461186457600080fd5b919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461186457600080fd5b600080600080600080600080610200898b0312156118aa57600080fd5b6118b48a8a611834565b97506118c38a60608b01611834565b96506118d28a60c08b01611834565b95506118e28a6101208b01611834565b945061018089013593506101a089013592506119016101c08a0161184c565b91506119106101e08a01611869565b90509295985092959890939650565b6000806000806000806101c0878903121561193957600080fd5b6119438888611834565b95506119528860608901611834565b94506119618860c08901611834565b9350611971886101208901611834565b925061018087013591506119886101a0880161184c565b90509295509295509295565b60008060008060006101a086880312156119ad57600080fd5b6119b78787611834565b94506119c68760608801611834565b93506119d58760c08801611834565b92506119e5876101208801611834565b91506119f4610180870161184c565b90509295509295909350565b600060208284031215611a1257600080fd5b611a1b82611869565b9392505050565b600080600060608486031215611a3757600080fd5b8351925060208401519150604084015190509250925092565b6000815180845260005b81811015611a7657602081850181015186830182015201611a5a565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000825160a06020840152611ad060c0840182611a50565b905073ffffffffffffffffffffffffffffffffffffffff60208501511660408401526040840151606084015260608401516080840152608084015160a08401528091505092915050565b600060208284031215611b2c57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115611b7557611b75611b33565b92915050565b8082028115828204841417611b7557611b75611b33565b600082611bc8577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60e08152845160e08201526000602086015160028110611c16577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b610100830152604086015173ffffffffffffffffffffffffffffffffffffffff166101208301526060860151611c6561014084018273ffffffffffffffffffffffffffffffffffffffff169052565b50608086015161016083015260a086015160c0610180840152611c8c6101a0840182611a50565b915050611cdb602083018673ffffffffffffffffffffffffffffffffffffffff808251168352602082015115156020840152806040830151166040840152506060810151151560608301525050565b60a082019390935260c001529291505056fea2646970667358221220b8c15c635ddfef51f1468cbcd54784b8ffca7ed8ac364d50d0548e33a0f2870064736f6c63430008120033000000000000000000000000ff1f2b4adb9df6fc8eafecdcbf96a2b351680455000000000000000000000000c52b9ae03d971954701b07090c57d993edcfbe79000000000000000000000000257c42571414ba714e81b968652f9c91d63a5b6600000000000000000000000015e27d72a6e95318e6b0e5e4a42b3b6ca22f09a7
Deployed Bytecode
0x6080604052600436106101485760003560e01c8063ad5c4648116100c0578063d9fb643a11610074578063e0bab4c411610059578063e0bab4c41461042d578063e2d51a7714610455578063f8e19cb11461048957600080fd5b8063d9fb643a146103df578063dbeacd541461040757600080fd5b8063ae9467b5116100a5578063ae9467b51461035b578063aedfdaea1461038f578063bb935cbf146103b757600080fd5b8063ad5c46481461030b578063ae4175b71461033357600080fd5b806389a302711161011757806396f50b2d116100fc57806396f50b2d1461029c5780639b07d342146102c4578063a5907215146102d757600080fd5b806389a302711461023257806394d0a7431461025a57600080fd5b806326c3b515146101545780632aa6584a1461018957806332fe7b26146101e25780636508156e1461020a57600080fd5b3661014f57005b600080fd5b61016761016236600461188d565b6104bd565b6040805193845260208401929092521515908201526060015b60405180910390f35b34801561019557600080fd5b506101bd7f000000000000000000000000257c42571414ba714e81b968652f9c91d63a5b6681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610180565b3480156101ee57600080fd5b506101bd73e592427a0aece92de3edee1f18e0157c0586156481565b34801561021657600080fd5b506101bd73abc30e831b5cc173a9ed5941714a7845c909e7fa81565b34801561023e57600080fd5b506101bd73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b34801561026657600080fd5b5061028e7f427a506ff6e15bd1b7e4e93da52c8ec95f6af1279618a2f076946e83d829499681565b604051908152602001610180565b3480156102a857600080fd5b506101bd73ba12222222228d8ba445958a75a0704d566bf2c881565b6101676102d236600461191f565b61068a565b3480156102e357600080fd5b506101bd7f00000000000000000000000015e27d72a6e95318e6b0e5e4a42b3b6ca22f09a781565b34801561031757600080fd5b506101bd73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b34801561033f57600080fd5b506101bd734169df1b7820702f566cc10938da51f6f597d26481565b34801561036757600080fd5b506101bd7f000000000000000000000000ff1f2b4adb9df6fc8eafecdcbf96a2b35168045581565b34801561039b57600080fd5b506101bd733c66b18f67ca6c1a71f829e2f6a0c987f97462d081565b3480156103c357600080fd5b506101bd7360897720aa966452e8706e74296b018990aec52781565b3480156103eb57600080fd5b506101bd737f39c581f595b53c5cb19bd0b3f8da6c935e2ca081565b34801561041357600080fd5b5061028e610422366004611994565b600095945050505050565b34801561043957600080fd5b506101bd736b175474e89094c44da98b954eedeac495271d0f81565b34801561046157600080fd5b506101bd7f000000000000000000000000c52b9ae03d971954701b07090c57d993edcfbe7981565b34801561049557600080fd5b5061028e7f32296969ef14eb0c6d29669c550d4a044913023000020000000000000000008081565b600080803373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ff1f2b4adb9df6fc8eafecdcbf96a2b3516804551614610530576040517f48f5c3ed00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b733c66b18f67ca6c1a71f829e2f6a0c987f97462d061055560408d0160208e01611a00565b73ffffffffffffffffffffffffffffffffffffffff16036105965761058b8761058460408c0160208d01611a00565b88886106c1565b92509250925061067c565b734169df1b7820702f566cc10938da51f6f597d2646105bb60408d0160208e01611a00565b73ffffffffffffffffffffffffffffffffffffffff16036105f05761058b876105ea60408c0160208d01611a00565b87610cc9565b7360897720aa966452e8706e74296b018990aec52761061560408d0160208e01611a00565b73ffffffffffffffffffffffffffffffffffffffff160361064a5761058b8761064460408c0160208d01611a00565b876111c5565b6040517fc582880b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b985098509895505050505050565b60008060006040517f26d18eab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808073ffffffffffffffffffffffffffffffffffffffff861615610713576040517f6c98dcaf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060007f000000000000000000000000c52b9ae03d971954701b07090c57d993edcfbe7973ffffffffffffffffffffffffffffffffffffffff16638277908b8b6107cd6040517fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660208201527f427a506ff6e15bd1b7e4e93da52c8ec95f6af1279618a2f076946e83d8294996603482015260009060540160405160208183030381529060405280519060200120905090565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b168152600481019290925260248201526044016060604051808303816000875af1158015610828573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084c9190611a22565b9194509250905081156109c1576040517f6b175474e89094c44da98b954eedeac495271d0f00000000000000000000000060208201527d64000000000000000000000000000000000000000000000000000000000060348201527fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006037820152600090604b01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815260a0830182528083523060208401524283830152606083018690526000608084015290517fc04b8d5900000000000000000000000000000000000000000000000000000000815290925073e592427a0aece92de3edee1f18e0157c058615649163c04b8d59916109709190600401611ab4565b6020604051808303816000875af115801561098f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b39190611b1a565b6109bd9083611b62565b9150505b8015610b30576040517fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000060208201527e01f4000000000000000000000000000000000000000000000000000000000060348201527fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006037820152600090604b01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815260a0830182528083523060208401524283830152606083018590526000608084015290517fc04b8d5900000000000000000000000000000000000000000000000000000000815290925073e592427a0aece92de3edee1f18e0157c058615649163c04b8d5991610adf9190600401611ab4565b6020604051808303816000875af1158015610afe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b229190611b1a565b610b2c9085611b62565b9350505b6000670de0b6b3a7640000610b4f67ffffffffffffffff8a168d611b7b565b610b599190611b92565b905080841015610b95576040517f8199f5f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810185905273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d90602401600060405180830381600087803b158015610bfb57600080fd5b505af1158015610c0f573d6000803e3d6000fd5b50506040517f12a53623000000000000000000000000000000000000000000000000000000008152600481018c90527f000000000000000000000000ff1f2b4adb9df6fc8eafecdcbf96a2b35168045573ffffffffffffffffffffffffffffffffffffffff1692506312a53623915086906024016000604051808303818588803b158015610c9c57600080fd5b505af1158015610cb0573d6000803e3d6000fd5b50969e60009e508e9d509b505050505050505050505050565b6000808073ffffffffffffffffffffffffffffffffffffffff8516736b175474e89094c44da98b954eedeac495271d0f14610d30576040517f6c98dcaf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060007f000000000000000000000000257c42571414ba714e81b968652f9c91d63a5b6673ffffffffffffffffffffffffffffffffffffffff16638277908b8a610dea6040517fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660208201527f427a506ff6e15bd1b7e4e93da52c8ec95f6af1279618a2f076946e83d8294996603482015260009060540160405160208183030381529060405280519060200120905090565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b168152600481019290925260248201526044016060604051808303816000875af1158015610e45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e699190611a22565b919450925090508215610fdf576040517fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000060208201527e01f4000000000000000000000000000000000000000000000000000000000060348201527fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006037820152600090604b01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815260a0830182528083523060208401524283830152606083018790526000608084015290517fc04b8d5900000000000000000000000000000000000000000000000000000000815290925073e592427a0aece92de3edee1f18e0157c058615649163c04b8d5991610f8e9190600401611ab4565b6020604051808303816000875af1158015610fad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd19190611b1a565b610fdb9083611b62565b9150505b801561114d576040517fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000060208201527d64000000000000000000000000000000000000000000000000000000000060348201527f6b175474e89094c44da98b954eedeac495271d0f0000000000000000000000006037820152600090604b01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815260a0830182528083523060208401524283830152606083018590526000608084015290517fc04b8d5900000000000000000000000000000000000000000000000000000000815290925073e592427a0aece92de3edee1f18e0157c058615649163c04b8d59916110fc9190600401611ab4565b6020604051808303816000875af115801561111b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061113f9190611b1a565b6111499084611b62565b9250505b6000670de0b6b3a764000061116c67ffffffffffffffff8a168c611b7b565b6111769190611b92565b9050808310156111b2576040517f8199f5f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5090986000985088975095505050505050565b6000808073ffffffffffffffffffffffffffffffffffffffff8516737f39c581f595b53c5cb19bd0b3f8da6c935e2ca01461122c576040517f6c98dcaf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060007f00000000000000000000000015e27d72a6e95318e6b0e5e4a42b3b6ca22f09a773ffffffffffffffffffffffffffffffffffffffff16638277908b8a6112e66040517fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660208201527f427a506ff6e15bd1b7e4e93da52c8ec95f6af1279618a2f076946e83d8294996603482015260009060540160405160208183030381529060405280519060200120905090565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b168152600481019290925260248201526044016060604051808303816000875af1158015611341573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113659190611a22565b9194509250905081156114da576040517f6b175474e89094c44da98b954eedeac495271d0f00000000000000000000000060208201527d64000000000000000000000000000000000000000000000000000000000060348201527fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006037820152600090604b01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815260a0830182528083523060208401524283830152606083018690526000608084015290517fc04b8d5900000000000000000000000000000000000000000000000000000000815290925073e592427a0aece92de3edee1f18e0157c058615649163c04b8d59916114899190600401611ab4565b6020604051808303816000875af11580156114a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114cc9190611b1a565b6114d69083611b62565b9150505b8015611649576040517fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000060208201527e01f4000000000000000000000000000000000000000000000000000000000060348201527fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006037820152600090604b01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815260a0830182528083523060208401524283830152606083018590526000608084015290517fc04b8d5900000000000000000000000000000000000000000000000000000000815290925073e592427a0aece92de3edee1f18e0157c058615649163c04b8d59916115f89190600401611ab4565b6020604051808303816000875af1158015611617573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163b9190611b1a565b6116459085611b62565b9350505b600083156117bc576040805160c0810182527f32296969ef14eb0c6d29669c550d4a044913023000020000000000000000008081526000602080830182905273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc283850152737f39c581f595b53c5cb19bd0b3f8da6c935e2ca060608085019190915260808085018a90528551808701875260048082527f30783030000000000000000000000000000000000000000000000000000000008286015260a087019190915286519182018752308083529382018590528187019390935290810183905293517f52bbbe2900000000000000000000000000000000000000000000000000000000815292939273ba12222222228d8ba445958a75a0704d566bf2c8926352bbbe299261177492879287929091429101611bcd565b6020604051808303816000875af1158015611793573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b79190611b1a565b925050505b6000670de0b6b3a76400006117db67ffffffffffffffff8b168d611b7b565b6117e59190611b92565b905080821015611821576040517f8199f5f300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5099600099508998509650505050505050565b60006060828403121561184657600080fd5b50919050565b803567ffffffffffffffff8116811461186457600080fd5b919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461186457600080fd5b600080600080600080600080610200898b0312156118aa57600080fd5b6118b48a8a611834565b97506118c38a60608b01611834565b96506118d28a60c08b01611834565b95506118e28a6101208b01611834565b945061018089013593506101a089013592506119016101c08a0161184c565b91506119106101e08a01611869565b90509295985092959890939650565b6000806000806000806101c0878903121561193957600080fd5b6119438888611834565b95506119528860608901611834565b94506119618860c08901611834565b9350611971886101208901611834565b925061018087013591506119886101a0880161184c565b90509295509295509295565b60008060008060006101a086880312156119ad57600080fd5b6119b78787611834565b94506119c68760608801611834565b93506119d58760c08801611834565b92506119e5876101208801611834565b91506119f4610180870161184c565b90509295509295909350565b600060208284031215611a1257600080fd5b611a1b82611869565b9392505050565b600080600060608486031215611a3757600080fd5b8351925060208401519150604084015190509250925092565b6000815180845260005b81811015611a7657602081850181015186830182015201611a5a565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000825160a06020840152611ad060c0840182611a50565b905073ffffffffffffffffffffffffffffffffffffffff60208501511660408401526040840151606084015260608401516080840152608084015160a08401528091505092915050565b600060208284031215611b2c57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115611b7557611b75611b33565b92915050565b8082028115828204841417611b7557611b75611b33565b600082611bc8577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60e08152845160e08201526000602086015160028110611c16577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b610100830152604086015173ffffffffffffffffffffffffffffffffffffffff166101208301526060860151611c6561014084018273ffffffffffffffffffffffffffffffffffffffff169052565b50608086015161016083015260a086015160c0610180840152611c8c6101a0840182611a50565b915050611cdb602083018673ffffffffffffffffffffffffffffffffffffffff808251168352602082015115156020840152806040830151166040840152506060810151151560608301525050565b60a082019390935260c001529291505056fea2646970667358221220b8c15c635ddfef51f1468cbcd54784b8ffca7ed8ac364d50d0548e33a0f2870064736f6c63430008120033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000ff1f2b4adb9df6fc8eafecdcbf96a2b351680455000000000000000000000000c52b9ae03d971954701b07090c57d993edcfbe79000000000000000000000000257c42571414ba714e81b968652f9c91d63a5b6600000000000000000000000015e27d72a6e95318e6b0e5e4a42b3b6ca22f09a7
-----Decoded View---------------
Arg [0] : _rollupProcessor (address): 0xFF1F2B4ADb9dF6FC8eAFecDcbF96A2B351680455
Arg [1] : _wethMigrator (address): 0xC52b9aE03d971954701B07090C57D993edCFbe79
Arg [2] : _daiMigrator (address): 0x257c42571414ba714e81B968652f9c91D63a5B66
Arg [3] : _wstethMigrator (address): 0x15e27d72a6E95318e6B0e5e4a42b3B6ca22F09A7
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000ff1f2b4adb9df6fc8eafecdcbf96a2b351680455
Arg [1] : 000000000000000000000000c52b9ae03d971954701b07090c57d993edcfbe79
Arg [2] : 000000000000000000000000257c42571414ba714e81b968652f9c91d63a5b66
Arg [3] : 00000000000000000000000015e27d72a6e95318e6b0e5e4a42b3b6ca22f09a7
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ 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.