Overview
APE Balance
0 APE
APE Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 4608609 | 19 hrs ago | IN | 0 APE | 0.05926287 |
Loading...
Loading
Contract Name:
Rewarder
Compiler Version
v0.7.5+commit.eb77ed08
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.7.5; pragma experimental ABIEncoderV2; import {IERC20} from './interfaces/IERC20.sol'; import {SafeERC20} from './libraries/SafeERC20.sol'; import {RewardsController} from './RewardsController.sol'; contract Rewarder is RewardsController { using SafeERC20 for IERC20; // reward => reward vault mapping(address => address) internal _rewardsVault; event RewardsVaultUpdated(address indexed vault); function setRewardsVault(address vault, address reward) external onlyOwner { _rewardsVault[reward] = vault; emit RewardsVaultUpdated(vault); } function getRewardsVault(address reward) external view returns (address) { return _rewardsVault[reward]; } function transferRewards(address to, address reward, uint256 amount) internal override returns (bool) { IERC20(reward).safeTransferFrom(_rewardsVault[reward], to, amount); return true; } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.5; /** * @dev Interface of the ERC20 standard as defined in the EIP. * From https://github.com/OpenZeppelin/openzeppelin-contracts */ 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: agpl-3.0 pragma solidity 0.7.5; import {IERC20} from './IERC20.sol'; interface IERC20Detailed is IERC20 { function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity 0.7.5; pragma experimental ABIEncoderV2; import {IRewardsDistributor} from './IRewardsDistributor.sol'; import {DistributionTypes} from '../libraries/DistributionTypes.sol'; interface IRewardsController is IRewardsDistributor { event RewardsClaimed( address indexed user, address indexed reward, address indexed to, address claimer, uint256 amount ); event ClaimerSet(address indexed user, address indexed claimer); function setClaimer(address user, address claimer) external; function getClaimer(address user) external view returns (address); function configureAssets(DistributionTypes.RewardsConfigInput[] memory config) external; function handleAction( address asset, uint256 userBalance, uint256 totalSupply ) external; function claimRewards( address[] calldata assets, uint256 amount, address to, address reward ) external returns (uint256); function claimRewardsOnBehalf( address[] calldata assets, uint256 amount, address user, address to, address reward ) external returns (uint256); function claimRewardsToSelf( address[] calldata assets, uint256 amount, address reward ) external returns (uint256); function claimAllRewards(address[] calldata assets, address to) external returns (address[] memory rewardsList, uint256[] memory claimedAmounts); function claimAllRewardsOnBehalf( address[] calldata assets, address user, address to ) external returns (address[] memory rewardsList, uint256[] memory claimedAmounts); function claimAllRewardsToSelf(address[] calldata assets) external returns (address[] memory rewardsList, uint256[] memory claimedAmounts); }
// SPDX-License-Identifier: MIT pragma solidity 0.7.5; pragma experimental ABIEncoderV2; import {DistributionTypes} from '../libraries/DistributionTypes.sol'; interface IRewardsDistributor { event AssetConfigUpdated( address indexed asset, address indexed reward, uint256 emission, uint256 distributionEnd ); event AssetIndexUpdated(address indexed asset, address indexed reward, uint256 index); event UserIndexUpdated( address indexed user, address indexed asset, address indexed reward, uint256 index ); event RewardsAccrued(address indexed user, address indexed reward, uint256 amount); function setDistributionEnd( address asset, address reward, uint32 distributionEnd ) external; function getDistributionEnd(address asset, address reward) external view returns (uint256); function getUserAssetData( address user, address asset, address reward ) external view returns (uint256); function getRewardsData(address asset, address reward) external view returns ( uint256, uint256, uint256, uint256 ); function getRewardsByAsset(address asset) external view returns (address[] memory); function getRewardTokens() external view returns (address[] memory); function getUserUnclaimedRewardsFromStorage(address user, address reward) external view returns (uint256); function getUserRewardsBalance( address[] calldata assets, address user, address reward ) external view returns (uint256); function getAllUserRewardsBalance(address[] calldata assets, address user) external view returns (address[] memory, uint256[] memory); function getAssetDecimals(address asset) external view returns (uint8); }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.5; interface IScaledBalanceToken { /** * @dev Returns the scaled balance of the user. The scaled balance is the sum of all the * updated stored balance divided by the reserve's liquidity index at the moment of the update * @param user The user whose balance is calculated * @return The scaled balance of the user **/ function scaledBalanceOf(address user) external view returns (uint256); /** * @dev Returns the scaled balance of the user and the scaled total supply. * @param user The address of the user * @return The scaled balance of the user * @return The scaled balance and the scaled total supply **/ function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256); /** * @dev Returns the scaled total supply of the token. Represents sum(debt/index) * @return The scaled total supply **/ function scaledTotalSupply() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.7.5; /** * @dev Collection of functions related to the address type * From https://github.com/OpenZeppelin/openzeppelin-contracts */ 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) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } /** * @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'); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{value: amount}(''); require(success, 'Address: unable to send value, recipient may have reverted'); } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.5; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.5; pragma experimental ABIEncoderV2; library DistributionTypes { struct RewardsConfigInput { uint88 emissionPerSecond; uint256 totalSupply; uint32 distributionEnd; address asset; address reward; } struct UserAssetInput { address underlyingAsset; uint256 userBalance; uint256 totalSupply; } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.5; import './Context.sol'; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(_owner == _msgSender(), 'Ownable: caller is not the owner'); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), 'Ownable: new owner is the zero address'); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.5; import {IERC20} from '../interfaces/IERC20.sol'; import {SafeMath} from './SafeMath.sol'; import {Address} from './Address.sol'; /** * @title SafeERC20 * @dev From https://github.com/OpenZeppelin/openzeppelin-contracts * 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 SafeMath for uint256; 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)); } function safeApprove( IERC20 token, address spender, uint256 value ) internal { 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 callOptionalReturn(IERC20 token, bytes memory data) private { require(address(token).isContract(), 'SafeERC20: call to non-contract'); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = address(token).call(data); require(success, 'SafeERC20: low-level call failed'); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), 'SafeERC20: ERC20 operation did not succeed'); } } }
// SPDX-License-Identifier: agpl-3.0 pragma solidity ^0.7.5; /** * @dev From https://github.com/OpenZeppelin/openzeppelin-contracts * Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @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) { uint256 c = a + b; require(c >= a, 'SafeMath: addition overflow'); return c; } /** * @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 sub(a, b, 'SafeMath: subtraction overflow'); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @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) { // 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 0; } uint256 c = a * b; require(c / a == b, 'SafeMath: multiplication overflow'); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts 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) internal pure returns (uint256) { return div(a, b, 'SafeMath: division by zero'); } /** * @dev Returns the integer division of two unsigned integers. Reverts 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) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts 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 mod(a, b, 'SafeMath: modulo by zero'); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message 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, string memory errorMessage ) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.5; pragma experimental ABIEncoderV2; import {IRewardsController} from './interfaces/IRewardsController.sol'; import {RewardsDistributor} from './RewardsDistributor.sol'; import {IScaledBalanceToken} from './interfaces/IScaledBalanceToken.sol'; import {DistributionTypes} from './libraries/DistributionTypes.sol'; abstract contract RewardsController is RewardsDistributor, IRewardsController { // user => authorized claimer mapping(address => address) internal _authorizedClaimers; modifier onlyAuthorizedClaimers(address claimer, address user) { require(_authorizedClaimers[user] == claimer, 'CLAIMER_UNAUTHORIZED'); _; } function getClaimer(address user) external view override returns (address) { return _authorizedClaimers[user]; } function setClaimer(address user, address caller) external override onlyOwner { _authorizedClaimers[user] = caller; emit ClaimerSet(user, caller); } function configureAssets(DistributionTypes.RewardsConfigInput[] memory config) external override onlyOwner { for (uint256 i = 0; i < config.length; i++) { config[i].totalSupply = IScaledBalanceToken(config[i].asset).scaledTotalSupply(); } _configureAssets(config); } function handleAction( address user, uint256 totalSupply, uint256 userBalance ) external override { _updateUserRewardsPerAssetInternal(msg.sender, user, userBalance, totalSupply); } function claimRewards( address[] calldata assets, uint256 amount, address to, address reward ) external override returns (uint256) { require(to != address(0), 'INVALID_TO_ADDRESS'); return _claimRewards(assets, amount, msg.sender, msg.sender, to, reward); } function claimRewardsOnBehalf( address[] calldata assets, uint256 amount, address user, address to, address reward ) external override onlyAuthorizedClaimers(msg.sender, user) returns (uint256) { require(user != address(0), 'INVALID_USER_ADDRESS'); require(to != address(0), 'INVALID_TO_ADDRESS'); return _claimRewards(assets, amount, msg.sender, user, to, reward); } function claimRewardsToSelf( address[] calldata assets, uint256 amount, address reward ) external override returns (uint256) { return _claimRewards(assets, amount, msg.sender, msg.sender, msg.sender, reward); } function claimAllRewards(address[] calldata assets, address to) external override returns (address[] memory rewardTokens, uint256[] memory claimedAmounts) { require(to != address(0), 'INVALID_TO_ADDRESS'); return _claimAllRewards(assets, msg.sender, msg.sender, to); } function claimAllRewardsOnBehalf( address[] calldata assets, address user, address to ) external override onlyAuthorizedClaimers(msg.sender, user) returns (address[] memory rewardTokens, uint256[] memory claimedAmounts) { require(user != address(0), 'INVALID_USER_ADDRESS'); require(to != address(0), 'INVALID_TO_ADDRESS'); return _claimAllRewards(assets, msg.sender, user, to); } function claimAllRewardsToSelf(address[] calldata assets) external override returns (address[] memory rewardTokens, uint256[] memory claimedAmounts) { return _claimAllRewards(assets, msg.sender, msg.sender, msg.sender); } function _getUserStake(address[] calldata assets, address user) internal view override returns (DistributionTypes.UserAssetInput[] memory userState) { userState = new DistributionTypes.UserAssetInput[](assets.length); for (uint256 i = 0; i < assets.length; i++) { userState[i].underlyingAsset = assets[i]; (userState[i].userBalance, userState[i].totalSupply) = IScaledBalanceToken(assets[i]) .getScaledUserBalanceAndSupply(user); } return userState; } function _claimRewards( address[] calldata assets, uint256 amount, address claimer, address user, address to, address reward ) internal returns (uint256) { if (amount == 0) { return 0; } uint256 unclaimedRewards = _usersUnclaimedRewards[user][reward]; if (amount > unclaimedRewards) { _distributeRewards(user, _getUserStake(assets, user)); unclaimedRewards = _usersUnclaimedRewards[user][reward]; } if (unclaimedRewards == 0) { return 0; } uint256 amountToClaim = amount > unclaimedRewards ? unclaimedRewards : amount; _usersUnclaimedRewards[user][reward] = unclaimedRewards - amountToClaim; // Safe due to the previous line _transferRewards(to, reward, amountToClaim); emit RewardsClaimed(user, reward, to, claimer, amountToClaim); return amountToClaim; } function _claimAllRewards( address[] calldata assets, address claimer, address user, address to ) internal returns (address[] memory rewardTokens, uint256[] memory claimedAmounts) { _distributeRewards(user, _getUserStake(assets, user)); rewardTokens = new address[](_rewardTokens.length); claimedAmounts = new uint256[](_rewardTokens.length); for (uint256 i = 0; i < _rewardTokens.length; i++) { address reward = _rewardTokens[i]; uint256 rewardAmount = _usersUnclaimedRewards[user][reward]; rewardTokens[i] = reward; claimedAmounts[i] = rewardAmount; if (rewardAmount != 0) { _usersUnclaimedRewards[user][reward] = 0; _transferRewards(to, reward, rewardAmount); emit RewardsClaimed(user, reward, to, claimer, rewardAmount); } } return (rewardTokens, claimedAmounts); } function _transferRewards( address to, address reward, uint256 amount ) internal { bool success = transferRewards(to, reward, amount); require(success == true, 'TRANSFER_ERROR'); } function transferRewards(address to, address reward, uint256 amount) internal virtual returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.7.5; pragma experimental ABIEncoderV2; import {IRewardsDistributor} from './interfaces/IRewardsDistributor.sol'; import {IERC20Detailed} from './interfaces/IERC20Detailed.sol'; import {DistributionTypes} from './libraries/DistributionTypes.sol'; import {Ownable} from './libraries/Ownable.sol'; abstract contract RewardsDistributor is IRewardsDistributor, Ownable { struct RewardData { uint88 emissionPerSecond; uint104 index; uint32 lastUpdateTimestamp; uint32 distributionEnd; mapping(address => uint256) usersIndex; } struct AssetData { // reward => rewardData mapping(address => RewardData) rewards; address[] availableRewards; uint8 decimals; } // incentivized asset => AssetData mapping(address => AssetData) internal _assets; // user => reward => unclaimed rewards mapping(address => mapping(address => uint256)) internal _usersUnclaimedRewards; // reward => isEnabled mapping(address => bool) internal _isRewardEnabled; address[] internal _rewardTokens; function getRewardsData(address asset, address reward) public view override returns ( uint256, uint256, uint256, uint256 ) { return ( _assets[asset].rewards[reward].index, _assets[asset].rewards[reward].emissionPerSecond, _assets[asset].rewards[reward].lastUpdateTimestamp, _assets[asset].rewards[reward].distributionEnd ); } function getDistributionEnd(address asset, address reward) external view override returns (uint256) { return _assets[asset].rewards[reward].distributionEnd; } function getRewardsByAsset(address asset) external view override returns (address[] memory) { return _assets[asset].availableRewards; } function getRewardTokens() external view override returns (address[] memory) { return _rewardTokens; } function getUserAssetData( address user, address asset, address reward ) public view override returns (uint256) { return _assets[asset].rewards[reward].usersIndex[user]; } function getUserUnclaimedRewardsFromStorage(address user, address reward) external view override returns (uint256) { return _usersUnclaimedRewards[user][reward]; } function getUserRewardsBalance( address[] calldata assets, address user, address reward ) external view override returns (uint256) { return _getUserReward(user, reward, _getUserStake(assets, user)); } function getAllUserRewardsBalance(address[] calldata assets, address user) external view override returns (address[] memory rewardTokens, uint256[] memory unclaimedAmounts) { return _getAllUserRewards(user, _getUserStake(assets, user)); } function setDistributionEnd( address asset, address reward, uint32 distributionEnd ) external override onlyOwner { _assets[asset].rewards[reward].distributionEnd = distributionEnd; emit AssetConfigUpdated( asset, reward, _assets[asset].rewards[reward].emissionPerSecond, distributionEnd ); } function _configureAssets(DistributionTypes.RewardsConfigInput[] memory rewardsInput) internal { for (uint256 i = 0; i < rewardsInput.length; i++) { _assets[rewardsInput[i].asset].decimals = IERC20Detailed(rewardsInput[i].asset).decimals(); RewardData storage rewardConfig = _assets[rewardsInput[i].asset].rewards[ rewardsInput[i].reward ]; // Add reward address to asset available rewards if latestUpdateTimestamp is zero if (rewardConfig.lastUpdateTimestamp == 0) { _assets[rewardsInput[i].asset].availableRewards.push(rewardsInput[i].reward); } // Add reward address to global rewards list if still not enabled if (_isRewardEnabled[rewardsInput[i].reward] == false) { _isRewardEnabled[rewardsInput[i].reward] = true; _rewardTokens.push(rewardsInput[i].reward); } // Due emissions is still zero, updates only latestUpdateTimestamp _updateAssetStateInternal( rewardsInput[i].asset, rewardsInput[i].reward, rewardConfig, rewardsInput[i].totalSupply, _assets[rewardsInput[i].asset].decimals ); // Configure emission and distribution end of the reward per asset rewardConfig.emissionPerSecond = rewardsInput[i].emissionPerSecond; rewardConfig.distributionEnd = rewardsInput[i].distributionEnd; emit AssetConfigUpdated( rewardsInput[i].asset, rewardsInput[i].reward, rewardsInput[i].emissionPerSecond, rewardsInput[i].distributionEnd ); } } function _updateAssetStateInternal( address asset, address reward, RewardData storage rewardConfig, uint256 totalSupply, uint8 decimals ) internal returns (uint256) { uint256 oldIndex = rewardConfig.index; if (block.timestamp == rewardConfig.lastUpdateTimestamp) { return oldIndex; } uint256 newIndex = _getAssetIndex( oldIndex, rewardConfig.emissionPerSecond, rewardConfig.lastUpdateTimestamp, rewardConfig.distributionEnd, totalSupply, decimals ); if (newIndex != oldIndex) { require(newIndex <= type(uint104).max, 'Index overflow'); //optimization: storing one after another saves one SSTORE rewardConfig.index = uint104(newIndex); rewardConfig.lastUpdateTimestamp = uint32(block.timestamp); emit AssetIndexUpdated(asset, reward, newIndex); } else { rewardConfig.lastUpdateTimestamp = uint32(block.timestamp); } return newIndex; } function _updateUserRewardsInternal( address user, address asset, address reward, uint256 userBalance, uint256 totalSupply ) internal returns (uint256) { RewardData storage rewardData = _assets[asset].rewards[reward]; uint256 userIndex = rewardData.usersIndex[user]; uint256 accruedRewards = 0; uint256 newIndex = _updateAssetStateInternal( asset, reward, rewardData, totalSupply, _assets[asset].decimals ); if (userIndex != newIndex) { if (userBalance != 0) { accruedRewards = _getRewards(userBalance, newIndex, userIndex, _assets[asset].decimals); } rewardData.usersIndex[user] = newIndex; emit UserIndexUpdated(user, asset, reward, newIndex); } return accruedRewards; } function _updateUserRewardsPerAssetInternal( address asset, address user, uint256 userBalance, uint256 totalSupply ) internal { for (uint256 r = 0; r < _assets[asset].availableRewards.length; r++) { address reward = _assets[asset].availableRewards[r]; uint256 accruedRewards = _updateUserRewardsInternal( user, asset, reward, userBalance, totalSupply ); if (accruedRewards != 0) { _usersUnclaimedRewards[user][reward] += accruedRewards; emit RewardsAccrued(user, reward, accruedRewards); } } } function _distributeRewards( address user, DistributionTypes.UserAssetInput[] memory userState ) internal { for (uint256 i = 0; i < userState.length; i++) { _updateUserRewardsPerAssetInternal( userState[i].underlyingAsset, user, userState[i].userBalance, userState[i].totalSupply ); } } function _getUserReward( address user, address reward, DistributionTypes.UserAssetInput[] memory userState ) internal view returns (uint256 unclaimedRewards) { // Add unrealized rewards for (uint256 i = 0; i < userState.length; i++) { if (userState[i].userBalance == 0) { continue; } unclaimedRewards += _getUnrealizedRewardsFromStake(user, reward, userState[i]); } // Return unrealized rewards plus stored unclaimed rewardss return unclaimedRewards + _usersUnclaimedRewards[user][reward]; } function _getAllUserRewards( address user, DistributionTypes.UserAssetInput[] memory userState ) internal view returns (address[] memory rewardTokens, uint256[] memory unclaimedRewards) { rewardTokens = new address[](_rewardTokens.length); unclaimedRewards = new uint256[](rewardTokens.length); // Add stored rewards from user to unclaimedRewards for (uint256 y = 0; y < rewardTokens.length; y++) { rewardTokens[y] = _rewardTokens[y]; unclaimedRewards[y] = _usersUnclaimedRewards[user][rewardTokens[y]]; } // Add unrealized rewards from user to unclaimedRewards for (uint256 i = 0; i < userState.length; i++) { if (userState[i].userBalance == 0) { continue; } for (uint256 r = 0; r < rewardTokens.length; r++) { unclaimedRewards[r] += _getUnrealizedRewardsFromStake(user, rewardTokens[r], userState[i]); } } return (rewardTokens, unclaimedRewards); } function _getUnrealizedRewardsFromStake( address user, address reward, DistributionTypes.UserAssetInput memory stake ) internal view returns (uint256) { RewardData storage rewardData = _assets[stake.underlyingAsset].rewards[reward]; uint8 assetDecimals = _assets[stake.underlyingAsset].decimals; uint256 assetIndex = _getAssetIndex( rewardData.index, rewardData.emissionPerSecond, rewardData.lastUpdateTimestamp, rewardData.distributionEnd, stake.totalSupply, assetDecimals ); return _getRewards(stake.userBalance, assetIndex, rewardData.usersIndex[user], assetDecimals); } function _getRewards( uint256 principalUserBalance, uint256 reserveIndex, uint256 userIndex, uint8 decimals ) internal pure returns (uint256) { return (principalUserBalance * (reserveIndex - userIndex)) / 10**decimals; } function _getAssetIndex( uint256 currentIndex, uint256 emissionPerSecond, uint128 lastUpdateTimestamp, uint256 distributionEnd, uint256 totalBalance, uint8 decimals ) internal view returns (uint256) { if ( emissionPerSecond == 0 || totalBalance == 0 || lastUpdateTimestamp == block.timestamp || lastUpdateTimestamp >= distributionEnd ) { return currentIndex; } uint256 currentTimestamp = block.timestamp > distributionEnd ? distributionEnd : block.timestamp; uint256 timeDelta = currentTimestamp - lastUpdateTimestamp; return (emissionPerSecond * timeDelta * (10**decimals)) / totalBalance + currentIndex; } function _getUserStake(address[] calldata assets, address user) internal view virtual returns (DistributionTypes.UserAssetInput[] memory userState); function getAssetDecimals(address asset) external view override returns (uint8) { return _assets[asset].decimals; } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"reward","type":"address"},{"indexed":false,"internalType":"uint256","name":"emission","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"distributionEnd","type":"uint256"}],"name":"AssetConfigUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"reward","type":"address"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"AssetIndexUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"claimer","type":"address"}],"name":"ClaimerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"reward","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardsAccrued","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"reward","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"claimer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardsClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vault","type":"address"}],"name":"RewardsVaultUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"reward","type":"address"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"UserIndexUpdated","type":"event"},{"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"address","name":"to","type":"address"}],"name":"claimAllRewards","outputs":[{"internalType":"address[]","name":"rewardTokens","type":"address[]"},{"internalType":"uint256[]","name":"claimedAmounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"claimAllRewardsOnBehalf","outputs":[{"internalType":"address[]","name":"rewardTokens","type":"address[]"},{"internalType":"uint256[]","name":"claimedAmounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"}],"name":"claimAllRewardsToSelf","outputs":[{"internalType":"address[]","name":"rewardTokens","type":"address[]"},{"internalType":"uint256[]","name":"claimedAmounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"reward","type":"address"}],"name":"claimRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"reward","type":"address"}],"name":"claimRewardsOnBehalf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"reward","type":"address"}],"name":"claimRewardsToSelf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint88","name":"emissionPerSecond","type":"uint88"},{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"uint32","name":"distributionEnd","type":"uint32"},{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"reward","type":"address"}],"internalType":"struct DistributionTypes.RewardsConfigInput[]","name":"config","type":"tuple[]"}],"name":"configureAssets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"address","name":"user","type":"address"}],"name":"getAllUserRewardsBalance","outputs":[{"internalType":"address[]","name":"rewardTokens","type":"address[]"},{"internalType":"uint256[]","name":"unclaimedAmounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getAssetDecimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getClaimer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"reward","type":"address"}],"name":"getDistributionEnd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRewardTokens","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getRewardsByAsset","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"reward","type":"address"}],"name":"getRewardsData","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"reward","type":"address"}],"name":"getRewardsVault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"reward","type":"address"}],"name":"getUserAssetData","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"reward","type":"address"}],"name":"getUserRewardsBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"reward","type":"address"}],"name":"getUserUnclaimedRewardsFromStorage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"uint256","name":"userBalance","type":"uint256"}],"name":"handleAction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"caller","type":"address"}],"name":"setClaimer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"reward","type":"address"},{"internalType":"uint32","name":"distributionEnd","type":"uint32"}],"name":"setDistributionEnd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"address","name":"reward","type":"address"}],"name":"setRewardsVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50600061001b61006a565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35061006e565b3390565b6128b78061007d6000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80637eff4ba8116100de578063bb492bf511610097578063c5a7b53811610071578063c5a7b53814610343578063c664493a14610356578063f2fde38b14610369578063f5cf673b1461037c57610173565b8063bb492bf514610315578063bf90f63a14610328578063c4f59f9b1461033b57610173565b80637eff4ba814610283578063866bc096146102a65780638da5cb5b146102b95780639efd6f72146102c15780639ff55db9146102e1578063af15ec5a1461030257610173565b80635077215511610130578063507721551461020257806357b89883146102155780636657732f1461022857806367eabbc914610248578063715018a61461026857806374d945ec1461027057610173565b80630b0db655146101785780631b839c771461018d578063236300dc146101b657806331873e2e146101c957806333028b99146101dc57806344fd1400146101ef575b600080fd5b61018b6101863660046124e3565b61038f565b005b6101a061019b3660046121e7565b6104aa565b6040516101ad919061279d565b60405180910390f35b6101a06101c43660046123fe565b6104e2565b61018b6101d7366004612294565b61052e565b6101a06101ea366004612469565b61053f565b61018b6101fd3660046121e7565b6105e6565b6101a0610210366004612219565b610695565b6101a06102233660046123af565b6106cf565b61023b6102363660046121c6565b6106e0565b6040516101ad919061265c565b61025b6102563660046121c6565b61075a565b6040516101ad919061262f565b61018b610778565b61025b61027e3660046121c6565b61081a565b6102966102913660046121e7565b610838565b6040516101ad94939291906127a6565b6101a06102b43660046121e7565b610897565b61025b6108c2565b6102d46102cf3660046121c6565b6108d1565b6040516101ad91906127e0565b6102f46102ef36600461234d565b6108f2565b6040516101ad92919061266f565b6101a061031036600461234d565b61099c565b6102f4610323366004612305565b6109b3565b6102f46103363660046122c6565b6109f5565b61023b610a11565b61018b61035136600461225b565b610a73565b6102f4610364366004612305565b610b5a565b61018b6103773660046121c6565b610b71565b61018b61038a3660046121e7565b610c69565b610397610d18565b6000546001600160a01b039081169116146103e7576040805162461bcd60e51b81526020600482018190526024820152600080516020612838833981519152604482015290519081900360640190fd5b60005b815181101561049d578181815181106103ff57fe5b6020026020010151606001516001600160a01b031663b1bf962d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561044357600080fd5b505afa158015610457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061047b9190612590565b82828151811061048757fe5b60209081029190910181015101526001016103ea565b506104a781610d1c565b50565b6001600160a01b039182166000908152600160209081526040808320939094168252919091522054600160e01b900463ffffffff1690565b60006001600160a01b0383166105135760405162461bcd60e51b815260040161050a9061271b565b60405180910390fd5b610522868686333388886111b9565b90505b95945050505050565b61053a338483856112ef565b505050565b6001600160a01b0380841660009081526005602052604081205490913391869116821461057e5760405162461bcd60e51b815260040161050a9061276f565b6001600160a01b0386166105a45760405162461bcd60e51b815260040161050a906126c5565b6001600160a01b0385166105ca5760405162461bcd60e51b815260040161050a9061271b565b6105d9898989338a8a8a6111b9565b9998505050505050505050565b6105ee610d18565b6000546001600160a01b0390811691161461063e576040805162461bcd60e51b81526020600482018190526024820152600080516020612838833981519152604482015290519081900360640190fd5b6001600160a01b0381811660009081526006602052604080822080546001600160a01b0319169386169384179055517f28a48cbce43190d77247f342cf319b1607bff4ef716cf26b76cf7bb71baebaa59190a25050565b6001600160a01b03808316600090815260016020818152604080842086861685528252808420948816845293909101905220549392505050565b6000610525858585333333886111b9565b6001600160a01b03811660009081526001602081815260409283902090910180548351818402810184019094528084526060939283018282801561074d57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161072f575b505050505090505b919050565b6001600160a01b039081166000908152600660205260409020541690565b610780610d18565b6000546001600160a01b039081169116146107d0576040805162461bcd60e51b81526020600482018190526024820152600080516020612838833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6001600160a01b039081166000908152600560205260409020541690565b6001600160a01b0391821660009081526001602090815260408083209390941682529190915220546001600160681b03600160581b820416916001600160581b0382169163ffffffff600160c01b8204811692600160e01b9092041690565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b6000546001600160a01b031690565b6001600160a01b031660009081526001602052604090206002015460ff1690565b6001600160a01b038083166000908152600560205260409020546060918291339186911682146109345760405162461bcd60e51b815260040161050a9061276f565b6001600160a01b03861661095a5760405162461bcd60e51b815260040161050a906126c5565b6001600160a01b0385166109805760405162461bcd60e51b815260040161050a9061271b565b61098d88883389896113e0565b93509350505094509492505050565b600061052583836109ae8888886115bc565b611742565b6060806001600160a01b0383166109dc5760405162461bcd60e51b815260040161050a9061271b565b6109e985853333876113e0565b91509150935093915050565b606080610a0584843333336113e0565b915091505b9250929050565b60606004805480602002602001604051908101604052809291908181526020018280548015610a6957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610a4b575b5050505050905090565b610a7b610d18565b6000546001600160a01b03908116911614610acb576040805162461bcd60e51b81526020600482018190526024820152600080516020612838833981519152604482015290519081900360640190fd5b6001600160a01b038381166000818152600160209081526040808320948716808452949091529081902080546001600160e01b0316600160e01b63ffffffff871602179081905590517fec44514a2743afadd78647150195ef92fec31e96087fa5cbbcd72e8d131d9a1c91610b4d916001600160581b039091169086906127c1565b60405180910390a3505050565b6060806109e983610b6c8787876115bc565b6117ce565b610b79610d18565b6000546001600160a01b03908116911614610bc9576040805162461bcd60e51b81526020600482018190526024820152600080516020612838833981519152604482015290519081900360640190fd5b6001600160a01b038116610c0e5760405162461bcd60e51b81526004018080602001828103825260268152602001806128126026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b610c71610d18565b6000546001600160a01b03908116911614610cc1576040805162461bcd60e51b81526020600482018190526024820152600080516020612838833981519152604482015290519081900360640190fd5b6001600160a01b0382811660008181526005602052604080822080546001600160a01b0319169486169485179055517f4925eafc82d0c4d67889898eeed64b18488ab19811e61620f387026dec126a289190a35050565b3390565b60005b81518110156111b557818181518110610d3457fe5b6020026020010151606001516001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610d7857600080fd5b505afa158015610d8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db091906125cb565b60016000848481518110610dc057fe5b6020026020010151606001516001600160a01b03166001600160a01b0316815260200190815260200160002060020160006101000a81548160ff021916908360ff160217905550600060016000848481518110610e1957fe5b6020026020010151606001516001600160a01b03166001600160a01b031681526020019081526020016000206000016000848481518110610e5657fe5b602090810291909101810151608001516001600160a01b031682528101919091526040016000208054909150600160c01b900463ffffffff16610f1e5760016000848481518110610ea357fe5b6020026020010151606001516001600160a01b03166001600160a01b03168152602001908152602001600020600101838381518110610ede57fe5b6020908102919091018101516080015182546001810184556000938452919092200180546001600160a01b0319166001600160a01b039092169190911790555b60036000848481518110610f2e57fe5b602090810291909101810151608001516001600160a01b031682528101919091526040016000205460ff1661100057600160036000858581518110610f6f57fe5b6020026020010151608001516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff0219169083151502179055506004838381518110610fc057fe5b6020908102919091018101516080015182546001810184556000938452919092200180546001600160a01b0319166001600160a01b039092169190911790555b61108f83838151811061100f57fe5b60200260200101516060015184848151811061102757fe5b6020026020010151608001518386868151811061104057fe5b6020026020010151602001516001600089898151811061105c57fe5b602090810291909101810151606001516001600160a01b031682528101919091526040016000206002015460ff166119d3565b5082828151811061109c57fe5b60209081029190910101515181546affffffffffffffffffffff19166001600160581b0390911617815582518390839081106110d457fe5b602090810291909101015160400151815463ffffffff909116600160e01b026001600160e01b03909116178155825183908390811061110f57fe5b6020026020010151608001516001600160a01b031683838151811061113057fe5b6020026020010151606001516001600160a01b03167fec44514a2743afadd78647150195ef92fec31e96087fa5cbbcd72e8d131d9a1c85858151811061117257fe5b60200260200101516000015186868151811061118a57fe5b6020026020010151604001516040516111a49291906127c1565b60405180910390a350600101610d1f565b5050565b6000856111c8575060006112e4565b6001600160a01b03808516600090815260026020908152604080832093861683529290522054808711156112325761120a856112058b8b896115bc565b611b1c565b506001600160a01b038085166000908152600260209081526040808320938616835292905220545b806112415760009150506112e4565b60008188116112505787611252565b815b6001600160a01b03808816600090815260026020908152604080832093891683529290522081840390559050611289858583611b81565b846001600160a01b0316846001600160a01b0316876001600160a01b03167fc052130bc4ef84580db505783484b067ea8b71b3bca78a7e12db7aea8658f0048a856040516112d8929190612643565b60405180910390a49150505b979650505050505050565b60005b6001600160a01b038516600090815260016020819052604090912001548110156113d9576001600160a01b038516600090815260016020819052604082200180548390811061133d57fe5b60009182526020822001546001600160a01b031691506113608688848888611bb8565b905080156113cf576001600160a01b0380871660008181526002602090815260408083209487168084529490915290819020805485019055517f68ac6b4d0eeedccf3df154188dfac62d18d2ac5eaac52ecd6e728e33ce75a1d4906113c690859061279d565b60405180910390a35b50506001016112f2565b5050505050565b6060806113f2846112058989886115bc565b6004546001600160401b038111801561140a57600080fd5b50604051908082528060200260200182016040528015611434578160200160208202803683370190505b506004549092506001600160401b038111801561145057600080fd5b5060405190808252806020026020018201604052801561147a578160200160208202803683370190505b50905060005b6004548110156115b15760006004828154811061149957fe5b60009182526020808320909101546001600160a01b0389811684526002835260408085209190921680855292529091205485519192509082908690859081106114de57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508084848151811061150b57fe5b602090810291909101015280156115a7576001600160a01b03808816600090815260026020908152604080832093861683529290529081205561154f868383611b81565b856001600160a01b0316826001600160a01b0316886001600160a01b03167fc052130bc4ef84580db505783484b067ea8b71b3bca78a7e12db7aea8658f0048b8560405161159e929190612643565b60405180910390a45b5050600101611480565b509550959350505050565b6060826001600160401b03811180156115d457600080fd5b5060405190808252806020026020018201604052801561160e57816020015b6115fb6120a0565b8152602001906001900390816115f35790505b50905060005b8381101561173a5784848281811061162857fe5b905060200201602081019061163d91906121c6565b82828151811061164957fe5b60209081029190910101516001600160a01b03909116905284848281811061166d57fe5b905060200201602081019061168291906121c6565b6001600160a01b0316630afbcdc9846040518263ffffffff1660e01b81526004016116ad919061262f565b604080518083038186803b1580156116c457600080fd5b505afa1580156116d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116fc91906125a8565b83838151811061170857fe5b602002602001015160200184848151811061171f57fe5b60209081029190910101516040019190915252600101611614565b509392505050565b6000805b825181101561179f5782818151811061175b57fe5b6020026020010151602001516000141561177457611797565b611792858585848151811061178557fe5b6020026020010151611cbf565b820191505b600101611746565b506001600160a01b03808516600090815260026020908152604080832093871683529290522054019392505050565b60045460609081906001600160401b03811180156117eb57600080fd5b50604051908082528060200260200182016040528015611815578160200160208202803683370190505b50915081516001600160401b038111801561182f57600080fd5b50604051908082528060200260200182016040528015611859578160200160208202803683370190505b50905060005b825181101561193a576004818154811061187557fe5b9060005260206000200160009054906101000a90046001600160a01b031683828151811061189f57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060026000866001600160a01b03166001600160a01b0316815260200190815260200160002060008483815181106118f257fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205482828151811061192757fe5b602090810291909101015260010161185f565b5060005b83518110156119cb5783818151811061195357fe5b6020026020010151602001516000141561196c576119c3565b60005b83518110156119c15761199c8685838151811061198857fe5b602002602001015187858151811061178557fe5b8382815181106119a857fe5b602090810291909101018051909101905260010161196f565b505b60010161193e565b509250929050565b8254600090600160581b81046001600160681b031690600160c01b900463ffffffff16421415611a04579050610525565b8454600090611a389083906001600160581b0381169063ffffffff600160c01b8204811691600160e01b9004168989611d81565b9050818114611af5576001600160681b03811115611a685760405162461bcd60e51b815260040161050a90612747565b85546cffffffffffffffffffffffffff60581b1916600160581b6001600160681b038316021763ffffffff60c01b1916600160c01b4263ffffffff16021786556040516001600160a01b0388811691908a16907f7ecfb468c92138c74e6034d3e9d76f99150e483bd53bcc43524ce7056698751f90611ae890859061279d565b60405180910390a36112e4565b855463ffffffff60c01b1916600160c01b4263ffffffff1602178655979650505050505050565b60005b815181101561053a57611b79828281518110611b3757fe5b60200260200101516000015184848481518110611b5057fe5b602002602001015160200151858581518110611b6857fe5b6020026020010151604001516112ef565b600101611b1f565b6000611b8e848484611e05565b9050600181151514611bb25760405162461bcd60e51b815260040161050a906126f3565b50505050565b6001600160a01b0380851660008181526001602081815260408084208987168552808352818520968c168552868401835290842054948452919052600201549092919083908190611c13908a908a9087908a9060ff166119d3565b9050808314611cb2578615611c53576001600160a01b038916600090815260016020526040902060020154611c509088908390869060ff16611e38565b91505b6001600160a01b03808b16600081815260018701602052604090819020849055518a8316928c1691907ff5674975ec2736b27b8d52ea7cafb8bc2761685f31f109e028e1498aa2b2f3e590611ca990869061279d565b60405180910390a45b5098975050505050505050565b80516001600160a01b03908116600090815260016020818152604080842087861685528252808420865190951684529190528082206002015483549185015192939260ff909116918491611d48916001600160681b03600160581b820416916001600160581b0382169163ffffffff600160c01b8204811692600160e01b909204169087611d81565b90506112e48560200151828560010160008b6001600160a01b03166001600160a01b031681526020019081526020016000205485611e38565b6000851580611d8e575082155b80611da1575042856001600160801b0316145b80611db5575083856001600160801b031610155b15611dc1575085611dfb565b6000844211611dd05742611dd2565b845b90506001600160801b0386168103888589830260ff8716600a0a0281611df457fe5b0401925050505b9695505050505050565b6001600160a01b038083166000818152600660205260408120549092611e2e9291168685611e57565b5060019392505050565b60008160ff16600a0a838503860281611e4d57fe5b0495945050505050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611bb2908590611ebe826001600160a01b0316612064565b611f0f576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310611f4d5780518252601f199092019160209182019101611f2e565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611faf576040519150601f19603f3d011682016040523d82523d6000602084013e611fb4565b606091505b50915091508161200b576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115611bb25780806020019051602081101561202757600080fd5b5051611bb25760405162461bcd60e51b815260040180806020018281038252602a815260200180612858602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061209857508115155b949350505050565b604051806060016040528060006001600160a01b0316815260200160008152602001600081525090565b80356001600160a01b038116811461075557600080fd5b60008083601f8401126120f2578182fd5b5081356001600160401b03811115612108578182fd5b6020830191508360208083028501011115610a0a57600080fd5b600060a08284031215612133578081fd5b60405160a081018181106001600160401b038211171561214f57fe5b60405290508082356001600160581b038116811461216c57600080fd5b815260208381013590820152612184604084016121b2565b6040820152612195606084016120ca565b60608201526121a6608084016120ca565b60808201525092915050565b803563ffffffff8116811461075557600080fd5b6000602082840312156121d7578081fd5b6121e0826120ca565b9392505050565b600080604083850312156121f9578081fd5b612202836120ca565b9150612210602084016120ca565b90509250929050565b60008060006060848603121561222d578081fd5b612236846120ca565b9250612244602085016120ca565b9150612252604085016120ca565b90509250925092565b60008060006060848603121561226f578283fd5b612278846120ca565b9250612286602085016120ca565b9150612252604085016121b2565b6000806000606084860312156122a8578283fd5b6122b1846120ca565b95602085013595506040909401359392505050565b600080602083850312156122d8578182fd5b82356001600160401b038111156122ed578283fd5b6122f9858286016120e1565b90969095509350505050565b600080600060408486031215612319578283fd5b83356001600160401b0381111561232e578384fd5b61233a868287016120e1565b90945092506122529050602085016120ca565b60008060008060608587031215612362578081fd5b84356001600160401b03811115612377578182fd5b612383878288016120e1565b90955093506123969050602086016120ca565b91506123a4604086016120ca565b905092959194509250565b600080600080606085870312156123c4578384fd5b84356001600160401b038111156123d9578485fd5b6123e5878288016120e1565b909550935050602085013591506123a4604086016120ca565b600080600080600060808688031215612415578081fd5b85356001600160401b0381111561242a578182fd5b612436888289016120e1565b9096509450506020860135925061244f604087016120ca565b915061245d606087016120ca565b90509295509295909350565b60008060008060008060a08789031215612481578384fd5b86356001600160401b03811115612496578485fd5b6124a289828a016120e1565b909750955050602087013593506124bb604088016120ca565b92506124c9606088016120ca565b91506124d7608088016120ca565b90509295509295509295565b600060208083850312156124f5578182fd5b82356001600160401b038082111561250b578384fd5b818501915085601f83011261251e578384fd5b81358181111561252a57fe5b61253784858302016127ee565b818152848101925083850160a0808402860187018a1015612556578788fd5b8795505b838610156125825761256c8a83612122565b855260019590950194938601939081019061255a565b509098975050505050505050565b6000602082840312156125a1578081fd5b5051919050565b600080604083850312156125ba578182fd5b505080516020909101519092909150565b6000602082840312156125dc578081fd5b815160ff811681146121e0578182fd5b6000815180845260208085019450808401835b838110156126245781516001600160a01b0316875295820195908201906001016125ff565b509495945050505050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6000602082526121e060208301846125ec565b60006040825261268260408301856125ec565b828103602084810191909152845180835285820192820190845b818110156126b85784518352938301939183019160010161269c565b5090979650505050505050565b602080825260149082015273494e56414c49445f555345525f4144445245535360601b604082015260600190565b6020808252600e908201526d2a2920a729a322a92fa2a92927a960911b604082015260600190565b602080825260129082015271494e56414c49445f544f5f4144445245535360701b604082015260600190565b6020808252600e908201526d496e646578206f766572666c6f7760901b604082015260600190565b60208082526014908201527310d3105253515497d5539055551213d49256915160621b604082015260600190565b90815260200190565b93845260208401929092526040830152606082015260800190565b6001600160581b0392909216825263ffffffff16602082015260400190565b60ff91909116815260200190565b6040518181016001600160401b038111828210171561280957fe5b60405291905056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220ec125919d2e26d0c53b9727952496a47da726b6381dfb9da84ec16851746a87364736f6c63430007050033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101735760003560e01c80637eff4ba8116100de578063bb492bf511610097578063c5a7b53811610071578063c5a7b53814610343578063c664493a14610356578063f2fde38b14610369578063f5cf673b1461037c57610173565b8063bb492bf514610315578063bf90f63a14610328578063c4f59f9b1461033b57610173565b80637eff4ba814610283578063866bc096146102a65780638da5cb5b146102b95780639efd6f72146102c15780639ff55db9146102e1578063af15ec5a1461030257610173565b80635077215511610130578063507721551461020257806357b89883146102155780636657732f1461022857806367eabbc914610248578063715018a61461026857806374d945ec1461027057610173565b80630b0db655146101785780631b839c771461018d578063236300dc146101b657806331873e2e146101c957806333028b99146101dc57806344fd1400146101ef575b600080fd5b61018b6101863660046124e3565b61038f565b005b6101a061019b3660046121e7565b6104aa565b6040516101ad919061279d565b60405180910390f35b6101a06101c43660046123fe565b6104e2565b61018b6101d7366004612294565b61052e565b6101a06101ea366004612469565b61053f565b61018b6101fd3660046121e7565b6105e6565b6101a0610210366004612219565b610695565b6101a06102233660046123af565b6106cf565b61023b6102363660046121c6565b6106e0565b6040516101ad919061265c565b61025b6102563660046121c6565b61075a565b6040516101ad919061262f565b61018b610778565b61025b61027e3660046121c6565b61081a565b6102966102913660046121e7565b610838565b6040516101ad94939291906127a6565b6101a06102b43660046121e7565b610897565b61025b6108c2565b6102d46102cf3660046121c6565b6108d1565b6040516101ad91906127e0565b6102f46102ef36600461234d565b6108f2565b6040516101ad92919061266f565b6101a061031036600461234d565b61099c565b6102f4610323366004612305565b6109b3565b6102f46103363660046122c6565b6109f5565b61023b610a11565b61018b61035136600461225b565b610a73565b6102f4610364366004612305565b610b5a565b61018b6103773660046121c6565b610b71565b61018b61038a3660046121e7565b610c69565b610397610d18565b6000546001600160a01b039081169116146103e7576040805162461bcd60e51b81526020600482018190526024820152600080516020612838833981519152604482015290519081900360640190fd5b60005b815181101561049d578181815181106103ff57fe5b6020026020010151606001516001600160a01b031663b1bf962d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561044357600080fd5b505afa158015610457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061047b9190612590565b82828151811061048757fe5b60209081029190910181015101526001016103ea565b506104a781610d1c565b50565b6001600160a01b039182166000908152600160209081526040808320939094168252919091522054600160e01b900463ffffffff1690565b60006001600160a01b0383166105135760405162461bcd60e51b815260040161050a9061271b565b60405180910390fd5b610522868686333388886111b9565b90505b95945050505050565b61053a338483856112ef565b505050565b6001600160a01b0380841660009081526005602052604081205490913391869116821461057e5760405162461bcd60e51b815260040161050a9061276f565b6001600160a01b0386166105a45760405162461bcd60e51b815260040161050a906126c5565b6001600160a01b0385166105ca5760405162461bcd60e51b815260040161050a9061271b565b6105d9898989338a8a8a6111b9565b9998505050505050505050565b6105ee610d18565b6000546001600160a01b0390811691161461063e576040805162461bcd60e51b81526020600482018190526024820152600080516020612838833981519152604482015290519081900360640190fd5b6001600160a01b0381811660009081526006602052604080822080546001600160a01b0319169386169384179055517f28a48cbce43190d77247f342cf319b1607bff4ef716cf26b76cf7bb71baebaa59190a25050565b6001600160a01b03808316600090815260016020818152604080842086861685528252808420948816845293909101905220549392505050565b6000610525858585333333886111b9565b6001600160a01b03811660009081526001602081815260409283902090910180548351818402810184019094528084526060939283018282801561074d57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161072f575b505050505090505b919050565b6001600160a01b039081166000908152600660205260409020541690565b610780610d18565b6000546001600160a01b039081169116146107d0576040805162461bcd60e51b81526020600482018190526024820152600080516020612838833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6001600160a01b039081166000908152600560205260409020541690565b6001600160a01b0391821660009081526001602090815260408083209390941682529190915220546001600160681b03600160581b820416916001600160581b0382169163ffffffff600160c01b8204811692600160e01b9092041690565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b6000546001600160a01b031690565b6001600160a01b031660009081526001602052604090206002015460ff1690565b6001600160a01b038083166000908152600560205260409020546060918291339186911682146109345760405162461bcd60e51b815260040161050a9061276f565b6001600160a01b03861661095a5760405162461bcd60e51b815260040161050a906126c5565b6001600160a01b0385166109805760405162461bcd60e51b815260040161050a9061271b565b61098d88883389896113e0565b93509350505094509492505050565b600061052583836109ae8888886115bc565b611742565b6060806001600160a01b0383166109dc5760405162461bcd60e51b815260040161050a9061271b565b6109e985853333876113e0565b91509150935093915050565b606080610a0584843333336113e0565b915091505b9250929050565b60606004805480602002602001604051908101604052809291908181526020018280548015610a6957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610a4b575b5050505050905090565b610a7b610d18565b6000546001600160a01b03908116911614610acb576040805162461bcd60e51b81526020600482018190526024820152600080516020612838833981519152604482015290519081900360640190fd5b6001600160a01b038381166000818152600160209081526040808320948716808452949091529081902080546001600160e01b0316600160e01b63ffffffff871602179081905590517fec44514a2743afadd78647150195ef92fec31e96087fa5cbbcd72e8d131d9a1c91610b4d916001600160581b039091169086906127c1565b60405180910390a3505050565b6060806109e983610b6c8787876115bc565b6117ce565b610b79610d18565b6000546001600160a01b03908116911614610bc9576040805162461bcd60e51b81526020600482018190526024820152600080516020612838833981519152604482015290519081900360640190fd5b6001600160a01b038116610c0e5760405162461bcd60e51b81526004018080602001828103825260268152602001806128126026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b610c71610d18565b6000546001600160a01b03908116911614610cc1576040805162461bcd60e51b81526020600482018190526024820152600080516020612838833981519152604482015290519081900360640190fd5b6001600160a01b0382811660008181526005602052604080822080546001600160a01b0319169486169485179055517f4925eafc82d0c4d67889898eeed64b18488ab19811e61620f387026dec126a289190a35050565b3390565b60005b81518110156111b557818181518110610d3457fe5b6020026020010151606001516001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610d7857600080fd5b505afa158015610d8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db091906125cb565b60016000848481518110610dc057fe5b6020026020010151606001516001600160a01b03166001600160a01b0316815260200190815260200160002060020160006101000a81548160ff021916908360ff160217905550600060016000848481518110610e1957fe5b6020026020010151606001516001600160a01b03166001600160a01b031681526020019081526020016000206000016000848481518110610e5657fe5b602090810291909101810151608001516001600160a01b031682528101919091526040016000208054909150600160c01b900463ffffffff16610f1e5760016000848481518110610ea357fe5b6020026020010151606001516001600160a01b03166001600160a01b03168152602001908152602001600020600101838381518110610ede57fe5b6020908102919091018101516080015182546001810184556000938452919092200180546001600160a01b0319166001600160a01b039092169190911790555b60036000848481518110610f2e57fe5b602090810291909101810151608001516001600160a01b031682528101919091526040016000205460ff1661100057600160036000858581518110610f6f57fe5b6020026020010151608001516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff0219169083151502179055506004838381518110610fc057fe5b6020908102919091018101516080015182546001810184556000938452919092200180546001600160a01b0319166001600160a01b039092169190911790555b61108f83838151811061100f57fe5b60200260200101516060015184848151811061102757fe5b6020026020010151608001518386868151811061104057fe5b6020026020010151602001516001600089898151811061105c57fe5b602090810291909101810151606001516001600160a01b031682528101919091526040016000206002015460ff166119d3565b5082828151811061109c57fe5b60209081029190910101515181546affffffffffffffffffffff19166001600160581b0390911617815582518390839081106110d457fe5b602090810291909101015160400151815463ffffffff909116600160e01b026001600160e01b03909116178155825183908390811061110f57fe5b6020026020010151608001516001600160a01b031683838151811061113057fe5b6020026020010151606001516001600160a01b03167fec44514a2743afadd78647150195ef92fec31e96087fa5cbbcd72e8d131d9a1c85858151811061117257fe5b60200260200101516000015186868151811061118a57fe5b6020026020010151604001516040516111a49291906127c1565b60405180910390a350600101610d1f565b5050565b6000856111c8575060006112e4565b6001600160a01b03808516600090815260026020908152604080832093861683529290522054808711156112325761120a856112058b8b896115bc565b611b1c565b506001600160a01b038085166000908152600260209081526040808320938616835292905220545b806112415760009150506112e4565b60008188116112505787611252565b815b6001600160a01b03808816600090815260026020908152604080832093891683529290522081840390559050611289858583611b81565b846001600160a01b0316846001600160a01b0316876001600160a01b03167fc052130bc4ef84580db505783484b067ea8b71b3bca78a7e12db7aea8658f0048a856040516112d8929190612643565b60405180910390a49150505b979650505050505050565b60005b6001600160a01b038516600090815260016020819052604090912001548110156113d9576001600160a01b038516600090815260016020819052604082200180548390811061133d57fe5b60009182526020822001546001600160a01b031691506113608688848888611bb8565b905080156113cf576001600160a01b0380871660008181526002602090815260408083209487168084529490915290819020805485019055517f68ac6b4d0eeedccf3df154188dfac62d18d2ac5eaac52ecd6e728e33ce75a1d4906113c690859061279d565b60405180910390a35b50506001016112f2565b5050505050565b6060806113f2846112058989886115bc565b6004546001600160401b038111801561140a57600080fd5b50604051908082528060200260200182016040528015611434578160200160208202803683370190505b506004549092506001600160401b038111801561145057600080fd5b5060405190808252806020026020018201604052801561147a578160200160208202803683370190505b50905060005b6004548110156115b15760006004828154811061149957fe5b60009182526020808320909101546001600160a01b0389811684526002835260408085209190921680855292529091205485519192509082908690859081106114de57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508084848151811061150b57fe5b602090810291909101015280156115a7576001600160a01b03808816600090815260026020908152604080832093861683529290529081205561154f868383611b81565b856001600160a01b0316826001600160a01b0316886001600160a01b03167fc052130bc4ef84580db505783484b067ea8b71b3bca78a7e12db7aea8658f0048b8560405161159e929190612643565b60405180910390a45b5050600101611480565b509550959350505050565b6060826001600160401b03811180156115d457600080fd5b5060405190808252806020026020018201604052801561160e57816020015b6115fb6120a0565b8152602001906001900390816115f35790505b50905060005b8381101561173a5784848281811061162857fe5b905060200201602081019061163d91906121c6565b82828151811061164957fe5b60209081029190910101516001600160a01b03909116905284848281811061166d57fe5b905060200201602081019061168291906121c6565b6001600160a01b0316630afbcdc9846040518263ffffffff1660e01b81526004016116ad919061262f565b604080518083038186803b1580156116c457600080fd5b505afa1580156116d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116fc91906125a8565b83838151811061170857fe5b602002602001015160200184848151811061171f57fe5b60209081029190910101516040019190915252600101611614565b509392505050565b6000805b825181101561179f5782818151811061175b57fe5b6020026020010151602001516000141561177457611797565b611792858585848151811061178557fe5b6020026020010151611cbf565b820191505b600101611746565b506001600160a01b03808516600090815260026020908152604080832093871683529290522054019392505050565b60045460609081906001600160401b03811180156117eb57600080fd5b50604051908082528060200260200182016040528015611815578160200160208202803683370190505b50915081516001600160401b038111801561182f57600080fd5b50604051908082528060200260200182016040528015611859578160200160208202803683370190505b50905060005b825181101561193a576004818154811061187557fe5b9060005260206000200160009054906101000a90046001600160a01b031683828151811061189f57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060026000866001600160a01b03166001600160a01b0316815260200190815260200160002060008483815181106118f257fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205482828151811061192757fe5b602090810291909101015260010161185f565b5060005b83518110156119cb5783818151811061195357fe5b6020026020010151602001516000141561196c576119c3565b60005b83518110156119c15761199c8685838151811061198857fe5b602002602001015187858151811061178557fe5b8382815181106119a857fe5b602090810291909101018051909101905260010161196f565b505b60010161193e565b509250929050565b8254600090600160581b81046001600160681b031690600160c01b900463ffffffff16421415611a04579050610525565b8454600090611a389083906001600160581b0381169063ffffffff600160c01b8204811691600160e01b9004168989611d81565b9050818114611af5576001600160681b03811115611a685760405162461bcd60e51b815260040161050a90612747565b85546cffffffffffffffffffffffffff60581b1916600160581b6001600160681b038316021763ffffffff60c01b1916600160c01b4263ffffffff16021786556040516001600160a01b0388811691908a16907f7ecfb468c92138c74e6034d3e9d76f99150e483bd53bcc43524ce7056698751f90611ae890859061279d565b60405180910390a36112e4565b855463ffffffff60c01b1916600160c01b4263ffffffff1602178655979650505050505050565b60005b815181101561053a57611b79828281518110611b3757fe5b60200260200101516000015184848481518110611b5057fe5b602002602001015160200151858581518110611b6857fe5b6020026020010151604001516112ef565b600101611b1f565b6000611b8e848484611e05565b9050600181151514611bb25760405162461bcd60e51b815260040161050a906126f3565b50505050565b6001600160a01b0380851660008181526001602081815260408084208987168552808352818520968c168552868401835290842054948452919052600201549092919083908190611c13908a908a9087908a9060ff166119d3565b9050808314611cb2578615611c53576001600160a01b038916600090815260016020526040902060020154611c509088908390869060ff16611e38565b91505b6001600160a01b03808b16600081815260018701602052604090819020849055518a8316928c1691907ff5674975ec2736b27b8d52ea7cafb8bc2761685f31f109e028e1498aa2b2f3e590611ca990869061279d565b60405180910390a45b5098975050505050505050565b80516001600160a01b03908116600090815260016020818152604080842087861685528252808420865190951684529190528082206002015483549185015192939260ff909116918491611d48916001600160681b03600160581b820416916001600160581b0382169163ffffffff600160c01b8204811692600160e01b909204169087611d81565b90506112e48560200151828560010160008b6001600160a01b03166001600160a01b031681526020019081526020016000205485611e38565b6000851580611d8e575082155b80611da1575042856001600160801b0316145b80611db5575083856001600160801b031610155b15611dc1575085611dfb565b6000844211611dd05742611dd2565b845b90506001600160801b0386168103888589830260ff8716600a0a0281611df457fe5b0401925050505b9695505050505050565b6001600160a01b038083166000818152600660205260408120549092611e2e9291168685611e57565b5060019392505050565b60008160ff16600a0a838503860281611e4d57fe5b0495945050505050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611bb2908590611ebe826001600160a01b0316612064565b611f0f576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310611f4d5780518252601f199092019160209182019101611f2e565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611faf576040519150601f19603f3d011682016040523d82523d6000602084013e611fb4565b606091505b50915091508161200b576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115611bb25780806020019051602081101561202757600080fd5b5051611bb25760405162461bcd60e51b815260040180806020018281038252602a815260200180612858602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061209857508115155b949350505050565b604051806060016040528060006001600160a01b0316815260200160008152602001600081525090565b80356001600160a01b038116811461075557600080fd5b60008083601f8401126120f2578182fd5b5081356001600160401b03811115612108578182fd5b6020830191508360208083028501011115610a0a57600080fd5b600060a08284031215612133578081fd5b60405160a081018181106001600160401b038211171561214f57fe5b60405290508082356001600160581b038116811461216c57600080fd5b815260208381013590820152612184604084016121b2565b6040820152612195606084016120ca565b60608201526121a6608084016120ca565b60808201525092915050565b803563ffffffff8116811461075557600080fd5b6000602082840312156121d7578081fd5b6121e0826120ca565b9392505050565b600080604083850312156121f9578081fd5b612202836120ca565b9150612210602084016120ca565b90509250929050565b60008060006060848603121561222d578081fd5b612236846120ca565b9250612244602085016120ca565b9150612252604085016120ca565b90509250925092565b60008060006060848603121561226f578283fd5b612278846120ca565b9250612286602085016120ca565b9150612252604085016121b2565b6000806000606084860312156122a8578283fd5b6122b1846120ca565b95602085013595506040909401359392505050565b600080602083850312156122d8578182fd5b82356001600160401b038111156122ed578283fd5b6122f9858286016120e1565b90969095509350505050565b600080600060408486031215612319578283fd5b83356001600160401b0381111561232e578384fd5b61233a868287016120e1565b90945092506122529050602085016120ca565b60008060008060608587031215612362578081fd5b84356001600160401b03811115612377578182fd5b612383878288016120e1565b90955093506123969050602086016120ca565b91506123a4604086016120ca565b905092959194509250565b600080600080606085870312156123c4578384fd5b84356001600160401b038111156123d9578485fd5b6123e5878288016120e1565b909550935050602085013591506123a4604086016120ca565b600080600080600060808688031215612415578081fd5b85356001600160401b0381111561242a578182fd5b612436888289016120e1565b9096509450506020860135925061244f604087016120ca565b915061245d606087016120ca565b90509295509295909350565b60008060008060008060a08789031215612481578384fd5b86356001600160401b03811115612496578485fd5b6124a289828a016120e1565b909750955050602087013593506124bb604088016120ca565b92506124c9606088016120ca565b91506124d7608088016120ca565b90509295509295509295565b600060208083850312156124f5578182fd5b82356001600160401b038082111561250b578384fd5b818501915085601f83011261251e578384fd5b81358181111561252a57fe5b61253784858302016127ee565b818152848101925083850160a0808402860187018a1015612556578788fd5b8795505b838610156125825761256c8a83612122565b855260019590950194938601939081019061255a565b509098975050505050505050565b6000602082840312156125a1578081fd5b5051919050565b600080604083850312156125ba578182fd5b505080516020909101519092909150565b6000602082840312156125dc578081fd5b815160ff811681146121e0578182fd5b6000815180845260208085019450808401835b838110156126245781516001600160a01b0316875295820195908201906001016125ff565b509495945050505050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6000602082526121e060208301846125ec565b60006040825261268260408301856125ec565b828103602084810191909152845180835285820192820190845b818110156126b85784518352938301939183019160010161269c565b5090979650505050505050565b602080825260149082015273494e56414c49445f555345525f4144445245535360601b604082015260600190565b6020808252600e908201526d2a2920a729a322a92fa2a92927a960911b604082015260600190565b602080825260129082015271494e56414c49445f544f5f4144445245535360701b604082015260600190565b6020808252600e908201526d496e646578206f766572666c6f7760901b604082015260600190565b60208082526014908201527310d3105253515497d5539055551213d49256915160621b604082015260600190565b90815260200190565b93845260208401929092526040830152606082015260800190565b6001600160581b0392909216825263ffffffff16602082015260400190565b60ff91909116815260200190565b6040518181016001600160401b038111828210171561280957fe5b60405291905056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220ec125919d2e26d0c53b9727952496a47da726b6381dfb9da84ec16851746a87364736f6c63430007050033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.