Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
AaveStrategy
Compiler Version
v0.8.7+commit.e28d00a7
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: agpl-3.0 pragma solidity ^0.8.0; /** * @title OUSD Aave Strategy * @notice Investment strategy for investing stablecoins via Aave * @author Origin Protocol Inc */ import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "./IAave.sol"; import { IERC20, InitializableAbstractStrategy } from "../utils/InitializableAbstractStrategy.sol"; import { IAaveStakedToken } from "./IAaveStakeToken.sol"; import { IAaveIncentivesController } from "./IAaveIncentivesController.sol"; contract AaveStrategy is InitializableAbstractStrategy { using SafeERC20 for IERC20; uint16 constant referralCode = 92; IAaveIncentivesController public incentivesController; IAaveStakedToken public stkAave; /** * Initializer for setting up strategy internal state. This overrides the * InitializableAbstractStrategy initializer as AAVE needs several extra * addresses for the rewards program. * @param _platformAddress Address of the AAVE pool * @param _vaultAddress Address of the vault * @param _rewardTokenAddresses Address of the AAVE token * @param _assets Addresses of supported assets * @param _pTokens Platform Token corresponding addresses * @param _incentivesAddress Address of the AAVE incentives controller * @param _stkAaveAddress Address of the stkAave contract */ function initialize( address _platformAddress, // AAVE pool address _vaultAddress, address[] calldata _rewardTokenAddresses, // AAVE address[] calldata _assets, address[] calldata _pTokens, address _incentivesAddress, address _stkAaveAddress ) external onlyGovernor initializer { incentivesController = IAaveIncentivesController(_incentivesAddress); stkAave = IAaveStakedToken(_stkAaveAddress); InitializableAbstractStrategy._initialize( _platformAddress, _vaultAddress, _rewardTokenAddresses, _assets, _pTokens ); } /** * @dev Deposit asset into Aave * @param _asset Address of asset to deposit * @param _amount Amount of asset to deposit */ function deposit(address _asset, uint256 _amount) external override onlyVault nonReentrant { _deposit(_asset, _amount); } /** * @dev Deposit asset into Aave * @param _asset Address of asset to deposit * @param _amount Amount of asset to deposit */ function _deposit(address _asset, uint256 _amount) internal { require(_amount > 0, "Must deposit something"); // Following line also doubles as a check that we are depositing // an asset that we support. emit Deposit(_asset, _getATokenFor(_asset), _amount); _getLendingPool().deposit(_asset, _amount, address(this), referralCode); } /** * @dev Deposit the entire balance of any supported asset into Aave */ function depositAll() external override onlyVault nonReentrant { for (uint256 i = 0; i < assetsMapped.length; i++) { uint256 balance = IERC20(assetsMapped[i]).balanceOf(address(this)); if (balance > 0) { _deposit(assetsMapped[i], balance); } } } /** * @dev Withdraw asset from Aave * @param _recipient Address to receive withdrawn asset * @param _asset Address of asset to withdraw * @param _amount Amount of asset to withdraw */ function withdraw( address _recipient, address _asset, uint256 _amount ) external override onlyVault nonReentrant { require(_amount > 0, "Must withdraw something"); require(_recipient != address(0), "Must specify recipient"); emit Withdrawal(_asset, _getATokenFor(_asset), _amount); uint256 actual = _getLendingPool().withdraw( _asset, _amount, address(this) ); require(actual == _amount, "Did not withdraw enough"); IERC20(_asset).safeTransfer(_recipient, _amount); } /** * @dev Remove all assets from platform and send them to Vault contract. */ function withdrawAll() external override onlyVaultOrGovernor nonReentrant { for (uint256 i = 0; i < assetsMapped.length; i++) { // Redeem entire balance of aToken IERC20 asset = IERC20(assetsMapped[i]); address aToken = _getATokenFor(assetsMapped[i]); uint256 balance = IERC20(aToken).balanceOf(address(this)); if (balance > 0) { uint256 actual = _getLendingPool().withdraw( address(asset), balance, address(this) ); require(actual == balance, "Did not withdraw enough"); // Transfer entire balance to Vault asset.safeTransfer( vaultAddress, asset.balanceOf(address(this)) ); } } } /** * @dev Get the total asset value held in the platform * @param _asset Address of the asset * @return balance Total value of the asset in the platform */ function checkBalance(address _asset) external view override returns (uint256 balance) { // Balance is always with token aToken decimals address aToken = _getATokenFor(_asset); balance = IERC20(aToken).balanceOf(address(this)); } /** * @dev Retuns bool indicating whether asset is supported by strategy * @param _asset Address of the asset */ function supportsAsset(address _asset) external view override returns (bool) { return assetToPToken[_asset] != address(0); } /** * @dev Approve the spending of all assets by their corresponding aToken, * if for some reason is it necessary. */ function safeApproveAllTokens() external override onlyGovernor nonReentrant { address lendingPool = address(_getLendingPool()); // approve the pool to spend the Asset for (uint256 i = 0; i < assetsMapped.length; i++) { address asset = assetsMapped[i]; // Safe approval IERC20(asset).safeApprove(lendingPool, 0); IERC20(asset).safeApprove(lendingPool, type(uint256).max); } } /** * @dev Internal method to respond to the addition of new asset / aTokens We need to give the AAVE lending pool approval to transfer the asset. * @param _asset Address of the asset to approve * @param _aToken Address of the aToken */ function _abstractSetPToken(address _asset, address _aToken) internal override { address lendingPool = address(_getLendingPool()); IERC20(_asset).safeApprove(lendingPool, 0); IERC20(_asset).safeApprove(lendingPool, type(uint256).max); } /** * @dev Get the aToken wrapped in the IERC20 interface for this asset. * Fails if the pToken doesn't exist in our mappings. * @param _asset Address of the asset * @return Corresponding aToken to this asset */ function _getATokenFor(address _asset) internal view returns (address) { address aToken = assetToPToken[_asset]; require(aToken != address(0), "aToken does not exist"); return aToken; } /** * @dev Get the current address of the Aave lending pool, which is the gateway to * depositing. * @return Current lending pool implementation */ function _getLendingPool() internal view returns (IAaveLendingPool) { address lendingPool = ILendingPoolAddressesProvider(platformAddress) .getLendingPool(); require(lendingPool != address(0), "Lending pool does not exist"); return IAaveLendingPool(lendingPool); } /** * @dev Collect stkAave, convert it to AAVE send to Vault. */ function collectRewardTokens() external override onlyHarvester nonReentrant { if (address(stkAave) == address(0)) { return; } // Check staked AAVE cooldown timer uint256 cooldown = stkAave.stakersCooldowns(address(this)); uint256 windowStart = cooldown + stkAave.COOLDOWN_SECONDS(); uint256 windowEnd = windowStart + stkAave.UNSTAKE_WINDOW(); // If inside the unlock window, then we can redeem stkAave // for AAVE and send it to the vault. if (block.timestamp > windowStart && block.timestamp <= windowEnd) { // Redeem to AAVE uint256 stkAaveBalance = stkAave.balanceOf(address(this)); stkAave.redeem(address(this), stkAaveBalance); // Transfer AAVE to harvesterAddress uint256 aaveBalance = IERC20(rewardTokenAddresses[0]).balanceOf( address(this) ); if (aaveBalance > 0) { IERC20(rewardTokenAddresses[0]).safeTransfer( harvesterAddress, aaveBalance ); } } // Collect avaiable rewards and restart the cooldown timer, if either of // those should be run. if (block.timestamp > windowStart || cooldown == 0) { // aToken addresses for incentives controller address[] memory aTokens = new address[](assetsMapped.length); for (uint256 i = 0; i < assetsMapped.length; i++) { aTokens[i] = _getATokenFor(assetsMapped[i]); } // 1. If we have rewards availabile, collect them uint256 pendingRewards = incentivesController.getRewardsBalance( aTokens, address(this) ); if (pendingRewards > 0) { // Because getting more stkAAVE from the incentives controller // with claimRewards() may push the stkAAVE cooldown time // forward, it is called after stakedAAVE has been turned into // AAVE. uint256 collected = incentivesController.claimRewards( aTokens, pendingRewards, address(this) ); require(collected == pendingRewards, "AAVE reward difference"); } // 2. Start cooldown counting down. if (stkAave.balanceOf(address(this)) > 0) { // Protected with if since cooldown call would revert // if no stkAave balance. stkAave.cooldown(); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IERC20.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)); } } /** * @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: agpl-3.0 pragma solidity ^0.8.0; /** * @dev Interface for Aaves Lending Pool * Documentation: https://developers.aave.com/#lendingpool */ interface IAaveLendingPool { /** * @dev Deposits an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. * - E.g. User deposits 100 USDC and gets in return 100 aUSDC * @param asset The address of the underlying asset to deposit * @param amount The amount to be deposited * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man **/ function deposit( address asset, uint256 amount, address onBehalfOf, uint16 referralCode ) external; /** * @dev Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC * @param asset The address of the underlying asset to withdraw * @param amount The underlying amount to be withdrawn * - Send the value type(uint256).max in order to withdraw the whole aToken balance * @param to Address that will receive the underlying, same as msg.sender if the user * wants to receive it on his own wallet, or a different address if the beneficiary is a * different wallet * @return The final amount withdrawn **/ function withdraw( address asset, uint256 amount, address to ) external returns (uint256); } /** * @dev Interface for Aaves Lending Pool * Documentation: https://developers.aave.com/#lendingpooladdressesprovider */ interface ILendingPoolAddressesProvider { /** * @notice Get the current address for Aave LendingPool * @dev Lending pool is the core contract on which to call deposit */ function getLendingPool() external view returns (address); }
// SPDX-License-Identifier: agpl-3.0 pragma solidity ^0.8.0; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { SafeMath } from "@openzeppelin/contracts/utils/math/SafeMath.sol"; import { Initializable } from "../utils/Initializable.sol"; import { Governable } from "../governance/Governable.sol"; abstract contract InitializableAbstractStrategy is Initializable, Governable { using SafeERC20 for IERC20; using SafeMath for uint256; event PTokenAdded(address indexed _asset, address _pToken); event PTokenRemoved(address indexed _asset, address _pToken); event Deposit(address indexed _asset, address _pToken, uint256 _amount); event Withdrawal(address indexed _asset, address _pToken, uint256 _amount); event RewardTokenCollected( address recipient, address rewardToken, uint256 amount ); event RewardTokenAddressesUpdated( address[] _oldAddresses, address[] _newAddresses ); event HarvesterAddressesUpdated( address _oldHarvesterAddress, address _newHarvesterAddress ); // Core address for the given platform address public platformAddress; address public vaultAddress; // asset => pToken (Platform Specific Token Address) mapping(address => address) public assetToPToken; // Full list of all assets supported here address[] internal assetsMapped; // Deprecated: Reward token address // slither-disable-next-line constable-states address public _deprecated_rewardTokenAddress; // Deprecated: now resides in Harvester's rewardTokenConfigs // slither-disable-next-line constable-states uint256 public _deprecated_rewardLiquidationThreshold; // Address of the one address allowed to collect reward tokens address public harvesterAddress; // Reward token addresses address[] public rewardTokenAddresses; // Reserved for future expansion int256[98] private _reserved; /** * @dev Internal initialize function, to set up initial internal state * @param _platformAddress Generic platform address * @param _vaultAddress Address of the Vault * @param _rewardTokenAddresses Address of reward token for platform * @param _assets Addresses of initial supported assets * @param _pTokens Platform Token corresponding addresses */ function initialize( address _platformAddress, address _vaultAddress, address[] calldata _rewardTokenAddresses, address[] calldata _assets, address[] calldata _pTokens ) external onlyGovernor initializer { InitializableAbstractStrategy._initialize( _platformAddress, _vaultAddress, _rewardTokenAddresses, _assets, _pTokens ); } function _initialize( address _platformAddress, address _vaultAddress, address[] calldata _rewardTokenAddresses, address[] memory _assets, address[] memory _pTokens ) internal { platformAddress = _platformAddress; vaultAddress = _vaultAddress; rewardTokenAddresses = _rewardTokenAddresses; uint256 assetCount = _assets.length; require(assetCount == _pTokens.length, "Invalid input arrays"); for (uint256 i = 0; i < assetCount; i++) { _setPTokenAddress(_assets[i], _pTokens[i]); } } /** * @dev Collect accumulated reward token and send to Vault. */ function collectRewardTokens() external virtual onlyHarvester nonReentrant { _collectRewardTokens(); } function _collectRewardTokens() internal { for (uint256 i = 0; i < rewardTokenAddresses.length; i++) { IERC20 rewardToken = IERC20(rewardTokenAddresses[i]); uint256 balance = rewardToken.balanceOf(address(this)); emit RewardTokenCollected( harvesterAddress, rewardTokenAddresses[i], balance ); rewardToken.safeTransfer(harvesterAddress, balance); } } /** * @dev Verifies that the caller is the Vault. */ modifier onlyVault() { require(msg.sender == vaultAddress, "Caller is not the Vault"); _; } /** * @dev Verifies that the caller is the Harvester. */ modifier onlyHarvester() { require(msg.sender == harvesterAddress, "Caller is not the Harvester"); _; } /** * @dev Verifies that the caller is the Vault or Governor. */ modifier onlyVaultOrGovernor() { require( msg.sender == vaultAddress || msg.sender == governor(), "Caller is not the Vault or Governor" ); _; } /** * @dev Set the reward token addresses. * @param _rewardTokenAddresses Address array of the reward token */ function setRewardTokenAddresses(address[] calldata _rewardTokenAddresses) external onlyGovernor { for (uint256 i = 0; i < _rewardTokenAddresses.length; i++) { require( _rewardTokenAddresses[i] != address(0), "Can not set an empty address as a reward token" ); } emit RewardTokenAddressesUpdated( rewardTokenAddresses, _rewardTokenAddresses ); rewardTokenAddresses = _rewardTokenAddresses; } /** * @dev Get the reward token addresses. * @return address[] the reward token addresses. */ function getRewardTokenAddresses() external view returns (address[] memory) { return rewardTokenAddresses; } /** * @dev Provide support for asset by passing its pToken address. * This method can only be called by the system Governor * @param _asset Address for the asset * @param _pToken Address for the corresponding platform token */ function setPTokenAddress(address _asset, address _pToken) external onlyGovernor { _setPTokenAddress(_asset, _pToken); } /** * @dev Remove a supported asset by passing its index. * This method can only be called by the system Governor * @param _assetIndex Index of the asset to be removed */ function removePToken(uint256 _assetIndex) external onlyGovernor { require(_assetIndex < assetsMapped.length, "Invalid index"); address asset = assetsMapped[_assetIndex]; address pToken = assetToPToken[asset]; if (_assetIndex < assetsMapped.length - 1) { assetsMapped[_assetIndex] = assetsMapped[assetsMapped.length - 1]; } assetsMapped.pop(); assetToPToken[asset] = address(0); emit PTokenRemoved(asset, pToken); } /** * @dev Provide support for asset by passing its pToken address. * Add to internal mappings and execute the platform specific, * abstract method `_abstractSetPToken` * @param _asset Address for the asset * @param _pToken Address for the corresponding platform token */ function _setPTokenAddress(address _asset, address _pToken) internal { require(assetToPToken[_asset] == address(0), "pToken already set"); require( _asset != address(0) && _pToken != address(0), "Invalid addresses" ); assetToPToken[_asset] = _pToken; assetsMapped.push(_asset); emit PTokenAdded(_asset, _pToken); _abstractSetPToken(_asset, _pToken); } /** * @dev Transfer token to governor. Intended for recovering tokens stuck in * strategy contracts, i.e. mistaken sends. * @param _asset Address for the asset * @param _amount Amount of the asset to transfer */ function transferToken(address _asset, uint256 _amount) public onlyGovernor { IERC20(_asset).safeTransfer(governor(), _amount); } /** * @dev Set the reward token addresses. * @param _harvesterAddress Address of the harvester */ function setHarvesterAddress(address _harvesterAddress) external onlyGovernor { harvesterAddress = _harvesterAddress; emit HarvesterAddressesUpdated(harvesterAddress, _harvesterAddress); } /*************************************** Abstract ****************************************/ function _abstractSetPToken(address _asset, address _pToken) internal virtual; function safeApproveAllTokens() external virtual; /** * @dev Deposit an amount of asset into the platform * @param _asset Address for the asset * @param _amount Units of asset to deposit */ function deposit(address _asset, uint256 _amount) external virtual; /** * @dev Deposit balance of all supported assets into the platform */ function depositAll() external virtual; /** * @dev Withdraw an amount of asset from the platform. * @param _recipient Address to which the asset should be sent * @param _asset Address of the asset * @param _amount Units of asset to withdraw */ function withdraw( address _recipient, address _asset, uint256 _amount ) external virtual; /** * @dev Withdraw all assets from strategy sending assets to Vault. */ function withdrawAll() external virtual; /** * @dev Get the total asset value held in the platform. * This includes any interest that was generated since depositing. * @param _asset Address of the asset * @return balance Total value of the asset in the platform */ function checkBalance(address _asset) external view virtual returns (uint256 balance); /** * @dev Check if an asset is supported. * @param _asset Address of the asset * @return bool Whether asset is supported */ function supportsAsset(address _asset) external view virtual returns (bool); }
// SPDX-License-Identifier: agpl-3.0 pragma solidity ^0.8.0; interface IAaveStakedToken { function COOLDOWN_SECONDS() external returns (uint256); function UNSTAKE_WINDOW() external returns (uint256); function balanceOf(address addr) external returns (uint256); function redeem(address to, uint256 amount) external; function stakersCooldowns(address addr) external returns (uint256); function cooldown() external; }
// SPDX-License-Identifier: agpl-3.0 pragma solidity ^0.8.0; interface IAaveIncentivesController { event RewardsAccrued(address indexed user, uint256 amount); event RewardsClaimed( address indexed user, address indexed to, uint256 amount ); event RewardsClaimed( address indexed user, address indexed to, address indexed claimer, uint256 amount ); event ClaimerSet(address indexed user, address indexed claimer); /* * @dev Returns the configuration of the distribution for a certain asset * @param asset The address of the reference asset of the distribution * @return The asset index, the emission per second and the last updated timestamp **/ function getAssetData(address asset) external view returns ( uint256, uint256, uint256 ); /** * @dev Whitelists an address to claim the rewards on behalf of another address * @param user The address of the user * @param claimer The address of the claimer */ function setClaimer(address user, address claimer) external; /** * @dev Returns the whitelisted claimer for a certain address (0x0 if not set) * @param user The address of the user * @return The claimer address */ function getClaimer(address user) external view returns (address); /** * @dev Configure assets for a certain rewards emission * @param assets The assets to incentivize * @param emissionsPerSecond The emission for each asset */ function configureAssets( address[] calldata assets, uint256[] calldata emissionsPerSecond ) external; /** * @dev Called by the corresponding asset on any update that affects the rewards distribution * @param asset The address of the user * @param userBalance The balance of the user of the asset in the lending pool * @param totalSupply The total supply of the asset in the lending pool **/ function handleAction( address asset, uint256 userBalance, uint256 totalSupply ) external; /** * @dev Returns the total of rewards of an user, already accrued + not yet accrued * @param user The address of the user * @return The rewards **/ function getRewardsBalance(address[] calldata assets, address user) external view returns (uint256); /** * @dev Claims reward for an user, on all the assets of the lending pool, * accumulating the pending rewards * @param amount Amount of rewards to claim * @param to Address that will be receiving the rewards * @return Rewards claimed **/ function claimRewards( address[] calldata assets, uint256 amount, address to ) external returns (uint256); /** * @dev Claims reward for an user on behalf, on all the assets of the * lending pool, accumulating the pending rewards. The caller must * be whitelisted via "allowClaimOnBehalf" function by the RewardsAdmin role manager * @param amount Amount of rewards to claim * @param user Address to check and claim rewards * @param to Address that will be receiving the rewards * @return Rewards claimed **/ function claimRewardsOnBehalf( address[] calldata assets, uint256 amount, address user, address to ) external returns (uint256); /** * @dev returns the unclaimed rewards of the user * @param user the address of the user * @return the unclaimed user rewards */ function getUserUnclaimedRewards(address user) external view returns (uint256); /** * @dev returns the unclaimed rewards of the user * @param user the address of the user * @param asset The asset to incentivize * @return the user index for the asset */ function getUserAssetData(address user, address asset) external view returns (uint256); /** * @dev for backward compatibility with previous implementation of the Incentives controller */ function REWARD_TOKEN() external view returns (address); /** * @dev for backward compatibility with previous implementation of the Incentives controller */ function PRECISION() external view returns (uint8); /** * @dev Gets the distribution end timestamp of the emissions */ function DISTRIBUTION_END() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, uint256 amount ) external returns (bool); /** * @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); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @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 * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 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://diligence.consensys.net/posts/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 functionCall(target, data, "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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(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) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(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) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason 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 { // 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 assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } }
// SPDX-License-Identifier: agpl-3.0 pragma solidity ^0.8.0; abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require( initializing || !initialized, "Initializable: contract is already initialized" ); bool isTopLevelCall = !initializing; if (isTopLevelCall) { initializing = true; initialized = true; } _; if (isTopLevelCall) { initializing = false; } } uint256[50] private ______gap; }
// SPDX-License-Identifier: agpl-3.0 pragma solidity ^0.8.0; /** * @title OUSD Governable Contract * @dev Copy of the openzeppelin Ownable.sol contract with nomenclature change * from owner to governor and renounce methods removed. Does not use * Context.sol like Ownable.sol does for simplification. * @author Origin Protocol Inc */ contract Governable { // Storage position of the owner and pendingOwner of the contract // keccak256("OUSD.governor"); bytes32 private constant governorPosition = 0x7bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a; // keccak256("OUSD.pending.governor"); bytes32 private constant pendingGovernorPosition = 0x44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db; // keccak256("OUSD.reentry.status"); bytes32 private constant reentryStatusPosition = 0x53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac4535; // See OpenZeppelin ReentrancyGuard implementation uint256 constant _NOT_ENTERED = 1; uint256 constant _ENTERED = 2; event PendingGovernorshipTransfer( address indexed previousGovernor, address indexed newGovernor ); event GovernorshipTransferred( address indexed previousGovernor, address indexed newGovernor ); /** * @dev Initializes the contract setting the deployer as the initial Governor. */ constructor() { _setGovernor(msg.sender); emit GovernorshipTransferred(address(0), _governor()); } /** * @dev Returns the address of the current Governor. */ function governor() public view returns (address) { return _governor(); } /** * @dev Returns the address of the current Governor. */ function _governor() internal view returns (address governorOut) { bytes32 position = governorPosition; assembly { governorOut := sload(position) } } /** * @dev Returns the address of the pending Governor. */ function _pendingGovernor() internal view returns (address pendingGovernor) { bytes32 position = pendingGovernorPosition; assembly { pendingGovernor := sload(position) } } /** * @dev Throws if called by any account other than the Governor. */ modifier onlyGovernor() { require(isGovernor(), "Caller is not the Governor"); _; } /** * @dev Returns true if the caller is the current Governor. */ function isGovernor() public view returns (bool) { return msg.sender == _governor(); } function _setGovernor(address newGovernor) internal { bytes32 position = governorPosition; assembly { sstore(position, newGovernor) } } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { bytes32 position = reentryStatusPosition; uint256 _reentry_status; assembly { _reentry_status := sload(position) } // On the first call to nonReentrant, _notEntered will be true require(_reentry_status != _ENTERED, "Reentrant call"); // Any calls to nonReentrant after this point will fail assembly { sstore(position, _ENTERED) } _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) assembly { sstore(position, _NOT_ENTERED) } } function _setPendingGovernor(address newGovernor) internal { bytes32 position = pendingGovernorPosition; assembly { sstore(position, newGovernor) } } /** * @dev Transfers Governance of the contract to a new account (`newGovernor`). * Can only be called by the current Governor. Must be claimed for this to complete * @param _newGovernor Address of the new Governor */ function transferGovernance(address _newGovernor) external onlyGovernor { _setPendingGovernor(_newGovernor); emit PendingGovernorshipTransfer(_governor(), _newGovernor); } /** * @dev Claim Governance of the contract to a new account (`newGovernor`). * Can only be called by the new Governor. */ function claimGovernance() external { require( msg.sender == _pendingGovernor(), "Only the pending Governor can complete the claim" ); _changeGovernor(msg.sender); } /** * @dev Change Governance of the contract to a new account (`newGovernor`). * @param _newGovernor Address of the new Governor */ function _changeGovernor(address _newGovernor) internal { require(_newGovernor != address(0), "New Governor is address(0)"); emit GovernorshipTransferred(_governor(), _newGovernor); _setGovernor(_newGovernor); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_asset","type":"address"},{"indexed":false,"internalType":"address","name":"_pToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousGovernor","type":"address"},{"indexed":true,"internalType":"address","name":"newGovernor","type":"address"}],"name":"GovernorshipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_oldHarvesterAddress","type":"address"},{"indexed":false,"internalType":"address","name":"_newHarvesterAddress","type":"address"}],"name":"HarvesterAddressesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_asset","type":"address"},{"indexed":false,"internalType":"address","name":"_pToken","type":"address"}],"name":"PTokenAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_asset","type":"address"},{"indexed":false,"internalType":"address","name":"_pToken","type":"address"}],"name":"PTokenRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousGovernor","type":"address"},{"indexed":true,"internalType":"address","name":"newGovernor","type":"address"}],"name":"PendingGovernorshipTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"_oldAddresses","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"_newAddresses","type":"address[]"}],"name":"RewardTokenAddressesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"address","name":"rewardToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardTokenCollected","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_asset","type":"address"},{"indexed":false,"internalType":"address","name":"_pToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Withdrawal","type":"event"},{"inputs":[],"name":"_deprecated_rewardLiquidationThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_deprecated_rewardTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"assetToPToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"checkBalance","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collectRewardTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depositAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getRewardTokenAddresses","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvesterAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"incentivesController","outputs":[{"internalType":"contract IAaveIncentivesController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_platformAddress","type":"address"},{"internalType":"address","name":"_vaultAddress","type":"address"},{"internalType":"address[]","name":"_rewardTokenAddresses","type":"address[]"},{"internalType":"address[]","name":"_assets","type":"address[]"},{"internalType":"address[]","name":"_pTokens","type":"address[]"},{"internalType":"address","name":"_incentivesAddress","type":"address"},{"internalType":"address","name":"_stkAaveAddress","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_platformAddress","type":"address"},{"internalType":"address","name":"_vaultAddress","type":"address"},{"internalType":"address[]","name":"_rewardTokenAddresses","type":"address[]"},{"internalType":"address[]","name":"_assets","type":"address[]"},{"internalType":"address[]","name":"_pTokens","type":"address[]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isGovernor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"platformAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assetIndex","type":"uint256"}],"name":"removePToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardTokenAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"safeApproveAllTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_harvesterAddress","type":"address"}],"name":"setHarvesterAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"address","name":"_pToken","type":"address"}],"name":"setPTokenAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_rewardTokenAddresses","type":"address[]"}],"name":"setRewardTokenAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stkAave","outputs":[{"internalType":"contract IAaveStakedToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"supportsAsset","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newGovernor","type":"address"}],"name":"transferGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"transferToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vaultAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"address","name":"_asset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b506100283360008051602062002e3583398151915255565b60008051602062002e35833981519152546040516001600160a01b03909116906000907fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a908290a3612db580620000806000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c8063853828b611610104578063c2e1e3f4116100a2578063dbe55e5611610071578063dbe55e56146103db578063de5f6268146103ee578063f6ca71b0146103f6578063f817bc631461040b57600080fd5b8063c2e1e3f41461039a578063c7af3352146103ad578063d38bfff4146103b5578063d9caed12146103c857600080fd5b806396d538bb116100de57806396d538bb1461032e578063aa388af614610341578063ad1728cb1461037f578063af1df2551461038757600080fd5b8063853828b6146103005780639136616a146103085780639688d2fc1461031b57600080fd5b806347e7ef24116101715780635f5152261161014b5780635f515226146102a657806367c7066c146102c75780637b2d9b2c146102da5780637e2d3a15146102ed57600080fd5b806347e7ef24146102835780635a063f63146102965780635d36b1901461029e57600080fd5b80631072cbea116101ad5780631072cbea146102375780632e6552011461024a578063430bf08a1461025d578063476062a41461027057600080fd5b80630c340a24146101d45780630ed57b3a146101f95780630fc3b4c41461020e575b600080fd5b6101dc610414565b6040516001600160a01b0390911681526020015b60405180910390f35b61020c6102073660046126fe565b610431565b005b6101dc61021c3660046126c4565b6035602052600090815260409020546001600160a01b031681565b61020c610245366004612917565b61046c565b6037546101dc906001600160a01b031681565b6034546101dc906001600160a01b031681565b609e546101dc906001600160a01b031681565b61020c610291366004612917565b6104ac565b61020c61051f565b61020c610c7c565b6102b96102b43660046126c4565b610d22565b6040519081526020016101f0565b6039546101dc906001600160a01b031681565b6101dc6102e83660046129a7565b610daf565b61020c6102fb3660046127f6565b610dd9565b61020c610f17565b61020c6103163660046129a7565b611240565b61020c610329366004612737565b61140b565b61020c61033c366004612943565b611514565b61036f61034f3660046126c4565b6001600160a01b0390811660009081526035602052604090205416151590565b60405190151581526020016101f0565b61020c61163a565b609d546101dc906001600160a01b031681565b61020c6103a83660046126c4565b611718565b61036f611797565b61020c6103c33660046126c4565b6117c8565b61020c6103d63660046128d6565b61186c565b6033546101dc906001600160a01b031681565b61020c611abe565b6103fe611c10565b6040516101f09190612a39565b6102b960385481565b600061042c600080516020612d608339815191525490565b905090565b610439611797565b61045e5760405162461bcd60e51b815260040161045590612bab565b60405180910390fd5b6104688282611c72565b5050565b610474611797565b6104905760405162461bcd60e51b815260040161045590612bab565b61046861049b610414565b6001600160a01b0384169083611dd7565b6034546001600160a01b031633146104d65760405162461bcd60e51b815260040161045590612b74565b600080516020612d40833981519152805460028114156105085760405162461bcd60e51b815260040161045590612c30565b600282556105168484611e3a565b50600190555050565b6039546001600160a01b031633146105795760405162461bcd60e51b815260206004820152601b60248201527f43616c6c6572206973206e6f74207468652048617276657374657200000000006044820152606401610455565b600080516020612d40833981519152805460028114156105ab5760405162461bcd60e51b815260040161045590612c30565b60028255609e546001600160a01b03166105c457610c75565b609e5460405163091030c360e01b81523060048201526000916001600160a01b03169063091030c390602401602060405180830381600087803b15801561060a57600080fd5b505af115801561061e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064291906129c0565b90506000609e60009054906101000a90046001600160a01b03166001600160a01b03166372b49d636040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561069657600080fd5b505af11580156106aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ce91906129c0565b6106d89083612c58565b90506000609e60009054906101000a90046001600160a01b03166001600160a01b031663359c4a966040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561072c57600080fd5b505af1158015610740573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076491906129c0565b61076e9083612c58565b9050814211801561077f5750804211155b1561094e57609e546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381600087803b1580156107ca57600080fd5b505af11580156107de573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080291906129c0565b609e546040516301e9a69560e41b8152306004820152602481018390529192506001600160a01b031690631e9a695090604401600060405180830381600087803b15801561084f57600080fd5b505af1158015610863573d6000803e3d6000fd5b505050506000603a60008154811061087d5761087d612cfe565b6000918252602090912001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b1580156108c957600080fd5b505afa1580156108dd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090191906129c0565b9050801561094b57603954603a805461094b926001600160a01b031691849160009061092f5761092f612cfe565b6000918252602090912001546001600160a01b03169190611dd7565b50505b8142118061095a575082155b15610c715760365460009067ffffffffffffffff81111561097d5761097d612d14565b6040519080825280602002602001820160405280156109a6578160200160208202803683370190505b50905060005b603654811015610a22576109e6603682815481106109cc576109cc612cfe565b6000918252602090912001546001600160a01b0316611f55565b8282815181106109f8576109f8612cfe565b6001600160a01b039092166020928302919091019091015280610a1a81612cb7565b9150506109ac565b50609d546040516345accf9360e11b81526000916001600160a01b031690638b599f2690610a569085903090600401612a4c565b60206040518083038186803b158015610a6e57600080fd5b505afa158015610a82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa691906129c0565b90508015610b8157609d54604051633111e7b360e01b81526000916001600160a01b031690633111e7b390610ae390869086903090600401612a76565b602060405180830381600087803b158015610afd57600080fd5b505af1158015610b11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3591906129c0565b9050818114610b7f5760405162461bcd60e51b8152602060048201526016602482015275414156452072657761726420646966666572656e636560501b6044820152606401610455565b505b609e546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381600087803b158015610bc757600080fd5b505af1158015610bdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bff91906129c0565b1115610c6e57609e60009054906101000a90046001600160a01b03166001600160a01b031663787a08a66040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610c5557600080fd5b505af1158015610c69573d6000803e3d6000fd5b505050505b50505b5050505b5060019055565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db546001600160a01b0316336001600160a01b031614610d175760405162461bcd60e51b815260206004820152603060248201527f4f6e6c79207468652070656e64696e6720476f7665726e6f722063616e20636f60448201526f6d706c6574652074686520636c61696d60801b6064820152608401610455565b610d2033611fbd565b565b600080610d2e83611f55565b6040516370a0823160e01b81523060048201529091506001600160a01b038216906370a082319060240160206040518083038186803b158015610d7057600080fd5b505afa158015610d84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da891906129c0565b9392505050565b603a8181548110610dbf57600080fd5b6000918252602090912001546001600160a01b0316905081565b610de1611797565b610dfd5760405162461bcd60e51b815260040161045590612bab565b600054610100900460ff1680610e16575060005460ff16155b610e325760405162461bcd60e51b815260040161045590612be2565b600054610100900460ff16158015610e54576000805461ffff19166101011790555b609d80546001600160a01b038086166001600160a01b031992831617909255609e8054928516929091169190911790556040805160208089028281018201909352888252610ef8928e928e928e928e92918e918e9182919085019084908082843760009201919091525050604080516020808f0282810182019093528e82529093508e92508d91829185019084908082843760009201919091525061208192505050565b8015610f0a576000805461ff00191690555b5050505050505050505050565b6034546001600160a01b0316331480610f485750610f33610414565b6001600160a01b0316336001600160a01b0316145b610fa05760405162461bcd60e51b815260206004820152602360248201527f43616c6c6572206973206e6f7420746865205661756c74206f7220476f7665726044820152623737b960e91b6064820152608401610455565b600080516020612d4083398151915280546002811415610fd25760405162461bcd60e51b815260040161045590612c30565b6002825560005b60365481101561123857600060368281548110610ff857610ff8612cfe565b6000918252602082200154603680546001600160a01b03909216935061102891859081106109cc576109cc612cfe565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038316906370a082319060240160206040518083038186803b15801561106d57600080fd5b505afa158015611081573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a591906129c0565b905080156112225760006110b761216a565b604051631a4ca37b60e21b81526001600160a01b0386811660048301526024820185905230604483015291909116906369328dec90606401602060405180830381600087803b15801561110957600080fd5b505af115801561111d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114191906129c0565b905081811461118c5760405162461bcd60e51b8152602060048201526017602482015276088d2c840dcdee840eed2e8d0c8e4c2ee40cadcdeeaced604b1b6044820152606401610455565b6034546040516370a0823160e01b8152306004820152611220916001600160a01b0390811691908716906370a082319060240160206040518083038186803b1580156111d757600080fd5b505afa1580156111eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061120f91906129c0565b6001600160a01b0387169190611dd7565b505b505050808061123090612cb7565b915050610fd9565b505060019055565b611248611797565b6112645760405162461bcd60e51b815260040161045590612bab565b60365481106112a55760405162461bcd60e51b815260206004820152600d60248201526c092dcecc2d8d2c840d2dcc8caf609b1b6044820152606401610455565b6000603682815481106112ba576112ba612cfe565b60009182526020808320909101546001600160a01b039081168084526035909252604090922054603654919350909116906112f790600190612c70565b831015611379576036805461130e90600190612c70565b8154811061131e5761131e612cfe565b600091825260209091200154603680546001600160a01b03909216918590811061134a5761134a612cfe565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b603680548061138a5761138a612ce8565b60008281526020808220600019908401810180546001600160a01b031990811690915593019093556001600160a01b038581168083526035855260409283902080549094169093559051908416815290917f16b7600acff27e39a8a96056b3d533045298de927507f5c1d97e4accde60488c910160405180910390a2505050565b611413611797565b61142f5760405162461bcd60e51b815260040161045590612bab565b600054610100900460ff1680611448575060005460ff16155b6114645760405162461bcd60e51b815260040161045590612be2565b600054610100900460ff16158015611486576000805461ffff19166101011790555b6114f78989898989898080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808d0282810182019093528c82529093508c92508b91829185019084908082843760009201919091525061208192505050565b8015611509576000805461ff00191690555b505050505050505050565b61151c611797565b6115385760405162461bcd60e51b815260040161045590612bab565b60005b818110156115ec57600083838381811061155757611557612cfe565b905060200201602081019061156c91906126c4565b6001600160a01b031614156115da5760405162461bcd60e51b815260206004820152602e60248201527f43616e206e6f742073657420616e20656d70747920616464726573732061732060448201526d30903932bbb0b932103a37b5b2b760911b6064820152608401610455565b806115e481612cb7565b91505061153b565b507f04c0b9649497d316554306e53678d5f5f5dbc3a06f97dec13ff4cfe98b986bbc603a838360405161162193929190612aa9565b60405180910390a1611635603a83836125f5565b505050565b611642611797565b61165e5760405162461bcd60e51b815260040161045590612bab565b600080516020612d40833981519152805460028114156116905760405162461bcd60e51b815260040161045590612c30565b60028255600061169e61216a565b905060005b60365481101561170e576000603682815481106116c2576116c2612cfe565b60009182526020822001546001600160a01b031691506116e59082908590612250565b6116fb6001600160a01b03821684600019612250565b508061170681612cb7565b9150506116a3565b5050600182555050565b611720611797565b61173c5760405162461bcd60e51b815260040161045590612bab565b603980546001600160a01b0319166001600160a01b0383169081179091556040805182815260208101929092527fe48386b84419f4d36e0f96c10cc3510b6fb1a33795620c5098b22472bbe90796910160405180910390a150565b60006117af600080516020612d608339815191525490565b6001600160a01b0316336001600160a01b031614905090565b6117d0611797565b6117ec5760405162461bcd60e51b815260040161045590612bab565b611814817f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db55565b806001600160a01b0316611834600080516020612d608339815191525490565b6001600160a01b03167fa39cc5eb22d0f34d8beaefee8a3f17cc229c1a1d1ef87a5ad47313487b1c4f0d60405160405180910390a350565b6034546001600160a01b031633146118965760405162461bcd60e51b815260040161045590612b74565b600080516020612d40833981519152805460028114156118c85760405162461bcd60e51b815260040161045590612c30565b600282556000831161191c5760405162461bcd60e51b815260206004820152601760248201527f4d75737420776974686472617720736f6d657468696e670000000000000000006044820152606401610455565b6001600160a01b03851661196b5760405162461bcd60e51b8152602060048201526016602482015275135d5cdd081cdc1958da599e481c9958da5c1a595b9d60521b6044820152606401610455565b836001600160a01b03167f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b639861199f86611f55565b604080516001600160a01b039092168252602082018790520160405180910390a260006119ca61216a565b604051631a4ca37b60e21b81526001600160a01b0387811660048301526024820187905230604483015291909116906369328dec90606401602060405180830381600087803b158015611a1c57600080fd5b505af1158015611a30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a5491906129c0565b9050838114611a9f5760405162461bcd60e51b8152602060048201526017602482015276088d2c840dcdee840eed2e8d0c8e4c2ee40cadcdeeaced604b1b6044820152606401610455565b611ab36001600160a01b0386168786611dd7565b505060019055505050565b6034546001600160a01b03163314611ae85760405162461bcd60e51b815260040161045590612b74565b600080516020612d4083398151915280546002811415611b1a5760405162461bcd60e51b815260040161045590612c30565b6002825560005b60365481101561123857600060368281548110611b4057611b40612cfe565b6000918252602090912001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015611b8c57600080fd5b505afa158015611ba0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc491906129c0565b90508015611bfd57611bfd60368381548110611be257611be2612cfe565b6000918252602090912001546001600160a01b031682611e3a565b5080611c0881612cb7565b915050611b21565b6060603a805480602002602001604051908101604052809291908181526020018280548015611c6857602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611c4a575b5050505050905090565b6001600160a01b038281166000908152603560205260409020541615611ccf5760405162461bcd60e51b81526020600482015260126024820152711c151bdad95b88185b1c9958591e481cd95d60721b6044820152606401610455565b6001600160a01b03821615801590611cef57506001600160a01b03811615155b611d2f5760405162461bcd60e51b8152602060048201526011602482015270496e76616c69642061646472657373657360781b6044820152606401610455565b6001600160a01b03828116600081815260356020908152604080832080549587166001600160a01b031996871681179091556036805460018101825594527f4a11f94e20a93c79f6ec743a1954ec4fc2c08429ae2122118bf234b2185c81b890930180549095168417909455925190815290917fef6485b84315f9b1483beffa32aae9a0596890395e3d7521f1c5fbb51790e765910160405180910390a26104688282612374565b6040516001600160a01b03831660248201526044810182905261163590849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526123ab565b60008111611e835760405162461bcd60e51b81526020600482015260166024820152754d757374206465706f73697420736f6d657468696e6760501b6044820152606401610455565b816001600160a01b03167f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62611eb784611f55565b604080516001600160a01b039092168252602082018590520160405180910390a2611ee061216a565b60405163e8eda9df60e01b81526001600160a01b03848116600483015260248201849052306044830152605c6064830152919091169063e8eda9df90608401600060405180830381600087803b158015611f3957600080fd5b505af1158015611f4d573d6000803e3d6000fd5b505050505050565b6001600160a01b0380821660009081526035602052604081205490911680611fb75760405162461bcd60e51b815260206004820152601560248201527418551bdad95b88191bd95cc81b9bdd08195e1a5cdd605a1b6044820152606401610455565b92915050565b6001600160a01b0381166120135760405162461bcd60e51b815260206004820152601a60248201527f4e657720476f7665726e6f7220697320616464726573732830290000000000006044820152606401610455565b806001600160a01b0316612033600080516020612d608339815191525490565b6001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a361207e81600080516020612d6083398151915255565b50565b603380546001600160a01b038089166001600160a01b03199283161790925560348054928816929091169190911790556120bd603a85856125f5565b508151815181146121075760405162461bcd60e51b8152602060048201526014602482015273496e76616c696420696e7075742061727261797360601b6044820152606401610455565b60005b818110156121605761214e84828151811061212757612127612cfe565b602002602001015184838151811061214157612141612cfe565b6020026020010151611c72565b8061215881612cb7565b91505061210a565b5050505050505050565b600080603360009054906101000a90046001600160a01b03166001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156121bb57600080fd5b505afa1580156121cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121f391906126e1565b90506001600160a01b03811661224b5760405162461bcd60e51b815260206004820152601b60248201527f4c656e64696e6720706f6f6c20646f6573206e6f7420657869737400000000006044820152606401610455565b919050565b8015806122d95750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b15801561229f57600080fd5b505afa1580156122b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d791906129c0565b155b6123445760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610455565b6040516001600160a01b03831660248201526044810182905261163590849063095ea7b360e01b90606401611e03565b600061237e61216a565b90506123956001600160a01b038416826000612250565b6116356001600160a01b03841682600019612250565b6000612400826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661247d9092919063ffffffff16565b805190915015611635578080602001905181019061241e9190612985565b6116355760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610455565b606061248c8484600085612494565b949350505050565b6060824710156124f55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610455565b843b6125435760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610455565b600080866001600160a01b0316858760405161255f9190612a1d565b60006040518083038185875af1925050503d806000811461259c576040519150601f19603f3d011682016040523d82523d6000602084013e6125a1565b606091505b50915091506125b18282866125bc565b979650505050505050565b606083156125cb575081610da8565b8251156125db5782518084602001fd5b8160405162461bcd60e51b81526004016104559190612b41565b828054828255906000526020600020908101928215612648579160200282015b828111156126485781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190612615565b50612654929150612658565b5090565b5b808211156126545760008155600101612659565b803561224b81612d2a565b60008083601f84011261268a57600080fd5b50813567ffffffffffffffff8111156126a257600080fd5b6020830191508360208260051b85010111156126bd57600080fd5b9250929050565b6000602082840312156126d657600080fd5b8135610da881612d2a565b6000602082840312156126f357600080fd5b8151610da881612d2a565b6000806040838503121561271157600080fd5b823561271c81612d2a565b9150602083013561272c81612d2a565b809150509250929050565b60008060008060008060008060a0898b03121561275357600080fd5b883561275e81612d2a565b9750602089013561276e81612d2a565b9650604089013567ffffffffffffffff8082111561278b57600080fd5b6127978c838d01612678565b909850965060608b01359150808211156127b057600080fd5b6127bc8c838d01612678565b909650945060808b01359150808211156127d557600080fd5b506127e28b828c01612678565b999c989b5096995094979396929594505050565b60008060008060008060008060008060e08b8d03121561281557600080fd5b8a3561282081612d2a565b995060208b013561283081612d2a565b985060408b013567ffffffffffffffff8082111561284d57600080fd5b6128598e838f01612678565b909a50985060608d013591508082111561287257600080fd5b61287e8e838f01612678565b909850965060808d013591508082111561289757600080fd5b506128a48d828e01612678565b90955093506128b7905060a08c0161266d565b91506128c560c08c0161266d565b90509295989b9194979a5092959850565b6000806000606084860312156128eb57600080fd5b83356128f681612d2a565b9250602084013561290681612d2a565b929592945050506040919091013590565b6000806040838503121561292a57600080fd5b823561293581612d2a565b946020939093013593505050565b6000806020838503121561295657600080fd5b823567ffffffffffffffff81111561296d57600080fd5b61297985828601612678565b90969095509350505050565b60006020828403121561299757600080fd5b81518015158114610da857600080fd5b6000602082840312156129b957600080fd5b5035919050565b6000602082840312156129d257600080fd5b5051919050565b600081518084526020808501945080840160005b83811015612a125781516001600160a01b0316875295820195908201906001016129ed565b509495945050505050565b60008251612a2f818460208701612c87565b9190910192915050565b602081526000610da860208301846129d9565b604081526000612a5f60408301856129d9565b905060018060a01b03831660208301529392505050565b606081526000612a8960608301866129d9565b6020830194909452506001600160a01b0391909116604090910152919050565b6000604082016040835280865480835260608501915087600052602092508260002060005b82811015612af35781546001600160a01b031684529284019260019182019101612ace565b505050838103828501528481528590820160005b86811015612b35578235612b1a81612d2a565b6001600160a01b031682529183019190830190600101612b07565b50979650505050505050565b6020815260008251806020840152612b60816040850160208701612c87565b601f01601f19169190910160400192915050565b60208082526017908201527f43616c6c6572206973206e6f7420746865205661756c74000000000000000000604082015260600190565b6020808252601a908201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252600e908201526d1499595b9d1c985b9d0818d85b1b60921b604082015260600190565b60008219821115612c6b57612c6b612cd2565b500190565b600082821015612c8257612c82612cd2565b500390565b60005b83811015612ca2578181015183820152602001612c8a565b83811115612cb1576000848401525b50505050565b6000600019821415612ccb57612ccb612cd2565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461207e57600080fdfe53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac45357bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4aa2646970667358221220ff929214198ce1b60e8f67eb426a61e89bb8935092be305112a315a0b827540e64736f6c634300080700337bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4a
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101cf5760003560e01c8063853828b611610104578063c2e1e3f4116100a2578063dbe55e5611610071578063dbe55e56146103db578063de5f6268146103ee578063f6ca71b0146103f6578063f817bc631461040b57600080fd5b8063c2e1e3f41461039a578063c7af3352146103ad578063d38bfff4146103b5578063d9caed12146103c857600080fd5b806396d538bb116100de57806396d538bb1461032e578063aa388af614610341578063ad1728cb1461037f578063af1df2551461038757600080fd5b8063853828b6146103005780639136616a146103085780639688d2fc1461031b57600080fd5b806347e7ef24116101715780635f5152261161014b5780635f515226146102a657806367c7066c146102c75780637b2d9b2c146102da5780637e2d3a15146102ed57600080fd5b806347e7ef24146102835780635a063f63146102965780635d36b1901461029e57600080fd5b80631072cbea116101ad5780631072cbea146102375780632e6552011461024a578063430bf08a1461025d578063476062a41461027057600080fd5b80630c340a24146101d45780630ed57b3a146101f95780630fc3b4c41461020e575b600080fd5b6101dc610414565b6040516001600160a01b0390911681526020015b60405180910390f35b61020c6102073660046126fe565b610431565b005b6101dc61021c3660046126c4565b6035602052600090815260409020546001600160a01b031681565b61020c610245366004612917565b61046c565b6037546101dc906001600160a01b031681565b6034546101dc906001600160a01b031681565b609e546101dc906001600160a01b031681565b61020c610291366004612917565b6104ac565b61020c61051f565b61020c610c7c565b6102b96102b43660046126c4565b610d22565b6040519081526020016101f0565b6039546101dc906001600160a01b031681565b6101dc6102e83660046129a7565b610daf565b61020c6102fb3660046127f6565b610dd9565b61020c610f17565b61020c6103163660046129a7565b611240565b61020c610329366004612737565b61140b565b61020c61033c366004612943565b611514565b61036f61034f3660046126c4565b6001600160a01b0390811660009081526035602052604090205416151590565b60405190151581526020016101f0565b61020c61163a565b609d546101dc906001600160a01b031681565b61020c6103a83660046126c4565b611718565b61036f611797565b61020c6103c33660046126c4565b6117c8565b61020c6103d63660046128d6565b61186c565b6033546101dc906001600160a01b031681565b61020c611abe565b6103fe611c10565b6040516101f09190612a39565b6102b960385481565b600061042c600080516020612d608339815191525490565b905090565b610439611797565b61045e5760405162461bcd60e51b815260040161045590612bab565b60405180910390fd5b6104688282611c72565b5050565b610474611797565b6104905760405162461bcd60e51b815260040161045590612bab565b61046861049b610414565b6001600160a01b0384169083611dd7565b6034546001600160a01b031633146104d65760405162461bcd60e51b815260040161045590612b74565b600080516020612d40833981519152805460028114156105085760405162461bcd60e51b815260040161045590612c30565b600282556105168484611e3a565b50600190555050565b6039546001600160a01b031633146105795760405162461bcd60e51b815260206004820152601b60248201527f43616c6c6572206973206e6f74207468652048617276657374657200000000006044820152606401610455565b600080516020612d40833981519152805460028114156105ab5760405162461bcd60e51b815260040161045590612c30565b60028255609e546001600160a01b03166105c457610c75565b609e5460405163091030c360e01b81523060048201526000916001600160a01b03169063091030c390602401602060405180830381600087803b15801561060a57600080fd5b505af115801561061e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064291906129c0565b90506000609e60009054906101000a90046001600160a01b03166001600160a01b03166372b49d636040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561069657600080fd5b505af11580156106aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ce91906129c0565b6106d89083612c58565b90506000609e60009054906101000a90046001600160a01b03166001600160a01b031663359c4a966040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561072c57600080fd5b505af1158015610740573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076491906129c0565b61076e9083612c58565b9050814211801561077f5750804211155b1561094e57609e546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381600087803b1580156107ca57600080fd5b505af11580156107de573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080291906129c0565b609e546040516301e9a69560e41b8152306004820152602481018390529192506001600160a01b031690631e9a695090604401600060405180830381600087803b15801561084f57600080fd5b505af1158015610863573d6000803e3d6000fd5b505050506000603a60008154811061087d5761087d612cfe565b6000918252602090912001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b1580156108c957600080fd5b505afa1580156108dd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090191906129c0565b9050801561094b57603954603a805461094b926001600160a01b031691849160009061092f5761092f612cfe565b6000918252602090912001546001600160a01b03169190611dd7565b50505b8142118061095a575082155b15610c715760365460009067ffffffffffffffff81111561097d5761097d612d14565b6040519080825280602002602001820160405280156109a6578160200160208202803683370190505b50905060005b603654811015610a22576109e6603682815481106109cc576109cc612cfe565b6000918252602090912001546001600160a01b0316611f55565b8282815181106109f8576109f8612cfe565b6001600160a01b039092166020928302919091019091015280610a1a81612cb7565b9150506109ac565b50609d546040516345accf9360e11b81526000916001600160a01b031690638b599f2690610a569085903090600401612a4c565b60206040518083038186803b158015610a6e57600080fd5b505afa158015610a82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa691906129c0565b90508015610b8157609d54604051633111e7b360e01b81526000916001600160a01b031690633111e7b390610ae390869086903090600401612a76565b602060405180830381600087803b158015610afd57600080fd5b505af1158015610b11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3591906129c0565b9050818114610b7f5760405162461bcd60e51b8152602060048201526016602482015275414156452072657761726420646966666572656e636560501b6044820152606401610455565b505b609e546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381600087803b158015610bc757600080fd5b505af1158015610bdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bff91906129c0565b1115610c6e57609e60009054906101000a90046001600160a01b03166001600160a01b031663787a08a66040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610c5557600080fd5b505af1158015610c69573d6000803e3d6000fd5b505050505b50505b5050505b5060019055565b7f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db546001600160a01b0316336001600160a01b031614610d175760405162461bcd60e51b815260206004820152603060248201527f4f6e6c79207468652070656e64696e6720476f7665726e6f722063616e20636f60448201526f6d706c6574652074686520636c61696d60801b6064820152608401610455565b610d2033611fbd565b565b600080610d2e83611f55565b6040516370a0823160e01b81523060048201529091506001600160a01b038216906370a082319060240160206040518083038186803b158015610d7057600080fd5b505afa158015610d84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da891906129c0565b9392505050565b603a8181548110610dbf57600080fd5b6000918252602090912001546001600160a01b0316905081565b610de1611797565b610dfd5760405162461bcd60e51b815260040161045590612bab565b600054610100900460ff1680610e16575060005460ff16155b610e325760405162461bcd60e51b815260040161045590612be2565b600054610100900460ff16158015610e54576000805461ffff19166101011790555b609d80546001600160a01b038086166001600160a01b031992831617909255609e8054928516929091169190911790556040805160208089028281018201909352888252610ef8928e928e928e928e92918e918e9182919085019084908082843760009201919091525050604080516020808f0282810182019093528e82529093508e92508d91829185019084908082843760009201919091525061208192505050565b8015610f0a576000805461ff00191690555b5050505050505050505050565b6034546001600160a01b0316331480610f485750610f33610414565b6001600160a01b0316336001600160a01b0316145b610fa05760405162461bcd60e51b815260206004820152602360248201527f43616c6c6572206973206e6f7420746865205661756c74206f7220476f7665726044820152623737b960e91b6064820152608401610455565b600080516020612d4083398151915280546002811415610fd25760405162461bcd60e51b815260040161045590612c30565b6002825560005b60365481101561123857600060368281548110610ff857610ff8612cfe565b6000918252602082200154603680546001600160a01b03909216935061102891859081106109cc576109cc612cfe565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038316906370a082319060240160206040518083038186803b15801561106d57600080fd5b505afa158015611081573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a591906129c0565b905080156112225760006110b761216a565b604051631a4ca37b60e21b81526001600160a01b0386811660048301526024820185905230604483015291909116906369328dec90606401602060405180830381600087803b15801561110957600080fd5b505af115801561111d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114191906129c0565b905081811461118c5760405162461bcd60e51b8152602060048201526017602482015276088d2c840dcdee840eed2e8d0c8e4c2ee40cadcdeeaced604b1b6044820152606401610455565b6034546040516370a0823160e01b8152306004820152611220916001600160a01b0390811691908716906370a082319060240160206040518083038186803b1580156111d757600080fd5b505afa1580156111eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061120f91906129c0565b6001600160a01b0387169190611dd7565b505b505050808061123090612cb7565b915050610fd9565b505060019055565b611248611797565b6112645760405162461bcd60e51b815260040161045590612bab565b60365481106112a55760405162461bcd60e51b815260206004820152600d60248201526c092dcecc2d8d2c840d2dcc8caf609b1b6044820152606401610455565b6000603682815481106112ba576112ba612cfe565b60009182526020808320909101546001600160a01b039081168084526035909252604090922054603654919350909116906112f790600190612c70565b831015611379576036805461130e90600190612c70565b8154811061131e5761131e612cfe565b600091825260209091200154603680546001600160a01b03909216918590811061134a5761134a612cfe565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b603680548061138a5761138a612ce8565b60008281526020808220600019908401810180546001600160a01b031990811690915593019093556001600160a01b038581168083526035855260409283902080549094169093559051908416815290917f16b7600acff27e39a8a96056b3d533045298de927507f5c1d97e4accde60488c910160405180910390a2505050565b611413611797565b61142f5760405162461bcd60e51b815260040161045590612bab565b600054610100900460ff1680611448575060005460ff16155b6114645760405162461bcd60e51b815260040161045590612be2565b600054610100900460ff16158015611486576000805461ffff19166101011790555b6114f78989898989898080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808d0282810182019093528c82529093508c92508b91829185019084908082843760009201919091525061208192505050565b8015611509576000805461ff00191690555b505050505050505050565b61151c611797565b6115385760405162461bcd60e51b815260040161045590612bab565b60005b818110156115ec57600083838381811061155757611557612cfe565b905060200201602081019061156c91906126c4565b6001600160a01b031614156115da5760405162461bcd60e51b815260206004820152602e60248201527f43616e206e6f742073657420616e20656d70747920616464726573732061732060448201526d30903932bbb0b932103a37b5b2b760911b6064820152608401610455565b806115e481612cb7565b91505061153b565b507f04c0b9649497d316554306e53678d5f5f5dbc3a06f97dec13ff4cfe98b986bbc603a838360405161162193929190612aa9565b60405180910390a1611635603a83836125f5565b505050565b611642611797565b61165e5760405162461bcd60e51b815260040161045590612bab565b600080516020612d40833981519152805460028114156116905760405162461bcd60e51b815260040161045590612c30565b60028255600061169e61216a565b905060005b60365481101561170e576000603682815481106116c2576116c2612cfe565b60009182526020822001546001600160a01b031691506116e59082908590612250565b6116fb6001600160a01b03821684600019612250565b508061170681612cb7565b9150506116a3565b5050600182555050565b611720611797565b61173c5760405162461bcd60e51b815260040161045590612bab565b603980546001600160a01b0319166001600160a01b0383169081179091556040805182815260208101929092527fe48386b84419f4d36e0f96c10cc3510b6fb1a33795620c5098b22472bbe90796910160405180910390a150565b60006117af600080516020612d608339815191525490565b6001600160a01b0316336001600160a01b031614905090565b6117d0611797565b6117ec5760405162461bcd60e51b815260040161045590612bab565b611814817f44c4d30b2eaad5130ad70c3ba6972730566f3e6359ab83e800d905c61b1c51db55565b806001600160a01b0316611834600080516020612d608339815191525490565b6001600160a01b03167fa39cc5eb22d0f34d8beaefee8a3f17cc229c1a1d1ef87a5ad47313487b1c4f0d60405160405180910390a350565b6034546001600160a01b031633146118965760405162461bcd60e51b815260040161045590612b74565b600080516020612d40833981519152805460028114156118c85760405162461bcd60e51b815260040161045590612c30565b600282556000831161191c5760405162461bcd60e51b815260206004820152601760248201527f4d75737420776974686472617720736f6d657468696e670000000000000000006044820152606401610455565b6001600160a01b03851661196b5760405162461bcd60e51b8152602060048201526016602482015275135d5cdd081cdc1958da599e481c9958da5c1a595b9d60521b6044820152606401610455565b836001600160a01b03167f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b639861199f86611f55565b604080516001600160a01b039092168252602082018790520160405180910390a260006119ca61216a565b604051631a4ca37b60e21b81526001600160a01b0387811660048301526024820187905230604483015291909116906369328dec90606401602060405180830381600087803b158015611a1c57600080fd5b505af1158015611a30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a5491906129c0565b9050838114611a9f5760405162461bcd60e51b8152602060048201526017602482015276088d2c840dcdee840eed2e8d0c8e4c2ee40cadcdeeaced604b1b6044820152606401610455565b611ab36001600160a01b0386168786611dd7565b505060019055505050565b6034546001600160a01b03163314611ae85760405162461bcd60e51b815260040161045590612b74565b600080516020612d4083398151915280546002811415611b1a5760405162461bcd60e51b815260040161045590612c30565b6002825560005b60365481101561123857600060368281548110611b4057611b40612cfe565b6000918252602090912001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015611b8c57600080fd5b505afa158015611ba0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc491906129c0565b90508015611bfd57611bfd60368381548110611be257611be2612cfe565b6000918252602090912001546001600160a01b031682611e3a565b5080611c0881612cb7565b915050611b21565b6060603a805480602002602001604051908101604052809291908181526020018280548015611c6857602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611c4a575b5050505050905090565b6001600160a01b038281166000908152603560205260409020541615611ccf5760405162461bcd60e51b81526020600482015260126024820152711c151bdad95b88185b1c9958591e481cd95d60721b6044820152606401610455565b6001600160a01b03821615801590611cef57506001600160a01b03811615155b611d2f5760405162461bcd60e51b8152602060048201526011602482015270496e76616c69642061646472657373657360781b6044820152606401610455565b6001600160a01b03828116600081815260356020908152604080832080549587166001600160a01b031996871681179091556036805460018101825594527f4a11f94e20a93c79f6ec743a1954ec4fc2c08429ae2122118bf234b2185c81b890930180549095168417909455925190815290917fef6485b84315f9b1483beffa32aae9a0596890395e3d7521f1c5fbb51790e765910160405180910390a26104688282612374565b6040516001600160a01b03831660248201526044810182905261163590849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526123ab565b60008111611e835760405162461bcd60e51b81526020600482015260166024820152754d757374206465706f73697420736f6d657468696e6760501b6044820152606401610455565b816001600160a01b03167f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62611eb784611f55565b604080516001600160a01b039092168252602082018590520160405180910390a2611ee061216a565b60405163e8eda9df60e01b81526001600160a01b03848116600483015260248201849052306044830152605c6064830152919091169063e8eda9df90608401600060405180830381600087803b158015611f3957600080fd5b505af1158015611f4d573d6000803e3d6000fd5b505050505050565b6001600160a01b0380821660009081526035602052604081205490911680611fb75760405162461bcd60e51b815260206004820152601560248201527418551bdad95b88191bd95cc81b9bdd08195e1a5cdd605a1b6044820152606401610455565b92915050565b6001600160a01b0381166120135760405162461bcd60e51b815260206004820152601a60248201527f4e657720476f7665726e6f7220697320616464726573732830290000000000006044820152606401610455565b806001600160a01b0316612033600080516020612d608339815191525490565b6001600160a01b03167fc7c0c772add429241571afb3805861fb3cfa2af374534088b76cdb4325a87e9a60405160405180910390a361207e81600080516020612d6083398151915255565b50565b603380546001600160a01b038089166001600160a01b03199283161790925560348054928816929091169190911790556120bd603a85856125f5565b508151815181146121075760405162461bcd60e51b8152602060048201526014602482015273496e76616c696420696e7075742061727261797360601b6044820152606401610455565b60005b818110156121605761214e84828151811061212757612127612cfe565b602002602001015184838151811061214157612141612cfe565b6020026020010151611c72565b8061215881612cb7565b91505061210a565b5050505050505050565b600080603360009054906101000a90046001600160a01b03166001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156121bb57600080fd5b505afa1580156121cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121f391906126e1565b90506001600160a01b03811661224b5760405162461bcd60e51b815260206004820152601b60248201527f4c656e64696e6720706f6f6c20646f6573206e6f7420657869737400000000006044820152606401610455565b919050565b8015806122d95750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b15801561229f57600080fd5b505afa1580156122b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d791906129c0565b155b6123445760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610455565b6040516001600160a01b03831660248201526044810182905261163590849063095ea7b360e01b90606401611e03565b600061237e61216a565b90506123956001600160a01b038416826000612250565b6116356001600160a01b03841682600019612250565b6000612400826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661247d9092919063ffffffff16565b805190915015611635578080602001905181019061241e9190612985565b6116355760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610455565b606061248c8484600085612494565b949350505050565b6060824710156124f55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610455565b843b6125435760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610455565b600080866001600160a01b0316858760405161255f9190612a1d565b60006040518083038185875af1925050503d806000811461259c576040519150601f19603f3d011682016040523d82523d6000602084013e6125a1565b606091505b50915091506125b18282866125bc565b979650505050505050565b606083156125cb575081610da8565b8251156125db5782518084602001fd5b8160405162461bcd60e51b81526004016104559190612b41565b828054828255906000526020600020908101928215612648579160200282015b828111156126485781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190612615565b50612654929150612658565b5090565b5b808211156126545760008155600101612659565b803561224b81612d2a565b60008083601f84011261268a57600080fd5b50813567ffffffffffffffff8111156126a257600080fd5b6020830191508360208260051b85010111156126bd57600080fd5b9250929050565b6000602082840312156126d657600080fd5b8135610da881612d2a565b6000602082840312156126f357600080fd5b8151610da881612d2a565b6000806040838503121561271157600080fd5b823561271c81612d2a565b9150602083013561272c81612d2a565b809150509250929050565b60008060008060008060008060a0898b03121561275357600080fd5b883561275e81612d2a565b9750602089013561276e81612d2a565b9650604089013567ffffffffffffffff8082111561278b57600080fd5b6127978c838d01612678565b909850965060608b01359150808211156127b057600080fd5b6127bc8c838d01612678565b909650945060808b01359150808211156127d557600080fd5b506127e28b828c01612678565b999c989b5096995094979396929594505050565b60008060008060008060008060008060e08b8d03121561281557600080fd5b8a3561282081612d2a565b995060208b013561283081612d2a565b985060408b013567ffffffffffffffff8082111561284d57600080fd5b6128598e838f01612678565b909a50985060608d013591508082111561287257600080fd5b61287e8e838f01612678565b909850965060808d013591508082111561289757600080fd5b506128a48d828e01612678565b90955093506128b7905060a08c0161266d565b91506128c560c08c0161266d565b90509295989b9194979a5092959850565b6000806000606084860312156128eb57600080fd5b83356128f681612d2a565b9250602084013561290681612d2a565b929592945050506040919091013590565b6000806040838503121561292a57600080fd5b823561293581612d2a565b946020939093013593505050565b6000806020838503121561295657600080fd5b823567ffffffffffffffff81111561296d57600080fd5b61297985828601612678565b90969095509350505050565b60006020828403121561299757600080fd5b81518015158114610da857600080fd5b6000602082840312156129b957600080fd5b5035919050565b6000602082840312156129d257600080fd5b5051919050565b600081518084526020808501945080840160005b83811015612a125781516001600160a01b0316875295820195908201906001016129ed565b509495945050505050565b60008251612a2f818460208701612c87565b9190910192915050565b602081526000610da860208301846129d9565b604081526000612a5f60408301856129d9565b905060018060a01b03831660208301529392505050565b606081526000612a8960608301866129d9565b6020830194909452506001600160a01b0391909116604090910152919050565b6000604082016040835280865480835260608501915087600052602092508260002060005b82811015612af35781546001600160a01b031684529284019260019182019101612ace565b505050838103828501528481528590820160005b86811015612b35578235612b1a81612d2a565b6001600160a01b031682529183019190830190600101612b07565b50979650505050505050565b6020815260008251806020840152612b60816040850160208701612c87565b601f01601f19169190910160400192915050565b60208082526017908201527f43616c6c6572206973206e6f7420746865205661756c74000000000000000000604082015260600190565b6020808252601a908201527f43616c6c6572206973206e6f742074686520476f7665726e6f72000000000000604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252600e908201526d1499595b9d1c985b9d0818d85b1b60921b604082015260600190565b60008219821115612c6b57612c6b612cd2565b500190565b600082821015612c8257612c82612cd2565b500390565b60005b83811015612ca2578181015183820152602001612c8a565b83811115612cb1576000848401525b50505050565b6000600019821415612ccb57612ccb612cd2565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461207e57600080fdfe53bf423e48ed90e97d02ab0ebab13b2a235a6bfbe9c321847d5c175333ac45357bea13895fa79d2831e0a9e28edede30099005a50d652d8957cf8a607ee6ca4aa2646970667358221220ff929214198ce1b60e8f67eb426a61e89bb8935092be305112a315a0b827540e64736f6c63430008070033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
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.