More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
GMatrixRewardPool
Compiler Version
v0.8.26+commit.8a97fa7a
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 /* ░▒▓██████████████▓▒░ ░▒▓██████▓▒░▒▓████████▓▒░▒▓███████▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓██████▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓████████▓▒░ ░▒▓█▓▒░ ░▒▓███████▓▒░░▒▓█▓▒░░▒▓██████▓▒░ ░▒▓████████▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ https://matrixai.finance/ */ pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "../interfaces/IBasisAsset.sol"; import "../interfaces/farming/IERC4626.sol"; import "../interfaces/farming/IShadowGauge.sol"; import "../interfaces/farming/ISwapxGauge.sol"; import "../interfaces/farming/IShadowVoter.sol"; import "../interfaces/farming/ISwapxVoter.sol"; import "../interfaces/farming/IX33.sol"; contract GMatrixRewardPool is ReentrancyGuard { using SafeMath for uint256; using SafeERC20 for IERC20; enum GaugeDex { NONE, SHADOW, SWAPX } // governance address public operator; // Info of each user. struct UserInfo { uint256 amount; // How many LP tokens the user has provided. uint256 rewardDebt; // Reward debt. See explanation below. } struct GaugeInfo { bool isGauge; // If this is a gauge address gauge; // The gauge GaugeDex gaugeDex; // Dex of the gauge } // Info of each pool. struct PoolInfo { IERC20 token; // Address of LP token contract. uint256 depFee; // deposit fee that is applied to created pool. uint256 allocPoint; // How many allocation points assigned to this pool. GMATRIXs to distribute per block. uint256 lastRewardTime; // Last time that GMATRIXs distribution occurs. uint256 accGmatrixPerShare; // Accumulated GMATRIXs per share, times 1e18. See below. bool isStarted; // if lastRewardTime has passed GaugeInfo gaugeInfo; // Gauge info (does this pool have a gauge and where is it) uint256 poolGmatrixPerSec; // rewards per second for pool (acts as allocPoint) } IERC20 public gmatrix; bool public claimGaugeRewardsOnUpdatePool = true; bool public mustConvertXSHADOW = true; IShadowVoter public shadowVoter; ISwapxVoter public swapxVoter; address public constant XSHADOW_TOKEN = 0x5050bc082FF4A74Fb6B0B04385dEfdDB114b2424; address public constant X33_TOKEN = 0x3333111A391cC08fa51353E9195526A70b333333; address public constant SWAPX_TOKEN = 0xA04BC7140c26fc9BB1F36B1A604C7A5a88fb0E70; address public devFund; // Info of each pool. PoolInfo[] public poolInfo; // Info of each user that stakes LP tokens. mapping(uint256 => mapping(address => UserInfo)) public userInfo; // Total allocation points. Must be the sum of all allocation points in all pools. uint256 public totalAllocPoint = 0; // The time when GMATRIX mining starts. uint256 public poolStartTime; // The time when GMATRIX mining ends. uint256 public poolEndTime; uint256 public sharePerSecond = 0 ether; uint256 public runningTime = 365 days; event Deposit(address indexed user, uint256 indexed pid, uint256 amount); event Withdraw(address indexed user, uint256 indexed pid, uint256 amount); event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount); event RewardPaid(address indexed user, uint256 amount); constructor( address _gmatrix, address _devFund, uint256 _poolStartTime, address _shadowVoter, address _swapxVoter ) { require(block.timestamp < _poolStartTime, "pool cant be started in the past"); if (_gmatrix != address(0)) gmatrix = IERC20(_gmatrix); if(_devFund != address(0)) devFund = _devFund; poolStartTime = _poolStartTime; poolEndTime = _poolStartTime + runningTime; operator = msg.sender; shadowVoter = IShadowVoter(_shadowVoter); swapxVoter = ISwapxVoter(_swapxVoter); devFund = _devFund; // create all the pools add(0, 0, IERC20(0x37C4c5e345ae4d4041b7f519343f942716fc6fE6), false, 0); // MATRIX-SONIC add(0, 0, IERC20(0x6BE3C7eF769FD208923105b048b31c547301c81a), false, 0); // GMATRIX-SONIC } modifier onlyOperator() { require(operator == msg.sender, "GMatrixRewardPool: caller is not the operator"); _; } function poolLength() external view returns (uint256) { return poolInfo.length; } function checkPoolDuplicate(IERC20 _token) internal view { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { require(poolInfo[pid].token != _token, "GMatrixRewardPool: existing pool?"); } } // Add new lp to the pool. Can only be called by operator. function add( uint256 _allocPoint, uint256 _depFee, IERC20 _token, bool _withUpdate, uint256 _lastRewardTime ) public onlyOperator { checkPoolDuplicate(_token); if (_withUpdate) { massUpdatePools(); } if (block.timestamp < poolStartTime) { // chef is sleeping if (_lastRewardTime == 0) { _lastRewardTime = poolStartTime; } else { if (_lastRewardTime < poolStartTime) { _lastRewardTime = poolStartTime; } } } else { // chef is cooking if (_lastRewardTime == 0 || _lastRewardTime < block.timestamp) { _lastRewardTime = block.timestamp; } } bool _isStarted = (_lastRewardTime <= poolStartTime) || (_lastRewardTime <= block.timestamp); poolInfo.push(PoolInfo({ token: _token, depFee: _depFee, allocPoint: _allocPoint, poolGmatrixPerSec: _allocPoint, lastRewardTime: _lastRewardTime, accGmatrixPerShare: 0, isStarted: _isStarted, gaugeInfo: GaugeInfo(false, address(0), GaugeDex.NONE) })); // enableGauge(poolInfo.length - 1); if (_isStarted) { totalAllocPoint = totalAllocPoint.add(_allocPoint); sharePerSecond = sharePerSecond.add(_allocPoint); } } // Update the given pool's GMATRIX allocation point. Can only be called by the operator. function set(uint256 _pid, uint256 _allocPoint, uint256 _depFee) public onlyOperator { massUpdatePools(); PoolInfo storage pool = poolInfo[_pid]; require(_depFee < 200); // deposit fee cant be more than 2%; pool.depFee = _depFee; if (pool.isStarted) { totalAllocPoint = totalAllocPoint.sub(pool.allocPoint).add(_allocPoint); sharePerSecond = sharePerSecond.sub(pool.poolGmatrixPerSec).add(_allocPoint); } pool.allocPoint = _allocPoint; pool.poolGmatrixPerSec = _allocPoint; } function bulkSet(uint256[] calldata _pids, uint256[] calldata _allocPoints, uint256[] calldata _depFees) external onlyOperator { require(_pids.length == _allocPoints.length && _pids.length == _depFees.length, "GMatrixRewardPool: invalid length"); for (uint256 i = 0; i < _pids.length; i++) { set(_pids[i], _allocPoints[i], _depFees[i]); } } // Return accumulate rewards over the given _from to _to block. function getGeneratedReward(uint256 _fromTime, uint256 _toTime) public view returns (uint256) { if (_fromTime >= _toTime) return 0; if (_toTime >= poolEndTime) { if (_fromTime >= poolEndTime) return 0; if (_fromTime <= poolStartTime) return poolEndTime.sub(poolStartTime).mul(sharePerSecond); return poolEndTime.sub(_fromTime).mul(sharePerSecond); } else { if (_toTime <= poolStartTime) return 0; if (_fromTime <= poolStartTime) return _toTime.sub(poolStartTime).mul(sharePerSecond); return _toTime.sub(_fromTime).mul(sharePerSecond); } } // View function to see pending GMATRIXs on frontend. function pendingShare(uint256 _pid, address _user) public view returns (uint256) { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_user]; uint256 accGmatrixPerShare = pool.accGmatrixPerShare; uint256 tokenSupply = pool.gaugeInfo.isGauge ? IShadowGauge(pool.gaugeInfo.gauge).balanceOf(address(this)) : pool.token.balanceOf(address(this)); if (block.timestamp > pool.lastRewardTime && tokenSupply != 0) { uint256 _generatedReward = getGeneratedReward(pool.lastRewardTime, block.timestamp); uint256 _gmatrixReward = _generatedReward.mul(pool.allocPoint).div(totalAllocPoint); accGmatrixPerShare = accGmatrixPerShare.add(_gmatrixReward.mul(1e18).div(tokenSupply)); } return user.amount.mul(accGmatrixPerShare).div(1e18).sub(user.rewardDebt); } function massUpdatePools() public { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { updatePool(pid); updatePoolWithGaugeDeposit(pid); } } // massUpdatePoolsInRange function massUpdatePoolsInRange(uint256 _fromPid, uint256 _toPid) public { require(_fromPid <= _toPid, "GMatrixRewardPool: invalid range"); for (uint256 pid = _fromPid; pid <= _toPid; ++pid) { updatePool(pid); updatePoolWithGaugeDeposit(pid); } } // Update reward variables of the given pool to be up-to-date. function updatePool(uint256 _pid) private { updatePoolWithGaugeDeposit(_pid); PoolInfo storage pool = poolInfo[_pid]; if (block.timestamp <= pool.lastRewardTime) { return; } uint256 tokenSupply = pool.gaugeInfo.isGauge ? IShadowGauge(pool.gaugeInfo.gauge).balanceOf(address(this)) : pool.token.balanceOf(address(this)); if (tokenSupply == 0) { pool.lastRewardTime = block.timestamp; return; } if (!pool.isStarted) { pool.isStarted = true; totalAllocPoint = totalAllocPoint.add(pool.allocPoint); sharePerSecond = sharePerSecond.add(pool.poolGmatrixPerSec); } if (totalAllocPoint > 0) { uint256 _generatedReward = getGeneratedReward(pool.lastRewardTime, block.timestamp); uint256 _gmatrixReward = _generatedReward.mul(pool.allocPoint).div(totalAllocPoint); pool.accGmatrixPerShare = pool.accGmatrixPerShare.add(_gmatrixReward.mul(1e18).div(tokenSupply)); } pool.lastRewardTime = block.timestamp; if (claimGaugeRewardsOnUpdatePool) {claimFarmRewards(_pid);} } // Deposit LP tokens to earn rewards function updatePoolWithGaugeDeposit(uint256 _pid) public { PoolInfo storage pool = poolInfo[_pid]; address gauge = pool.gaugeInfo.gauge; uint256 balance = pool.token.balanceOf(address(this)); // Do nothing if this pool doesn't have a gauge if (pool.gaugeInfo.isGauge) { // Do nothing if the LP token in the MC is empty if (balance > 0) { // Approve to the gauge if (pool.token.allowance(address(this), gauge) < balance ){ pool.token.approve(gauge, type(uint256).max); } // Deposit the LP in the gauge IShadowGauge(pool.gaugeInfo.gauge).deposit(balance); // NOTE: no need to check if gauge is shadow or swapx, because both have the same function } } } // Claim rewards to treasury function claimFarmRewards(uint256 _pid) public onlyOperator { PoolInfo storage pool = poolInfo[_pid]; if (pool.gaugeInfo.isGauge) { if (pool.gaugeInfo.gaugeDex == GaugeDex.SHADOW) { _claimShadowRewards(_pid); } if (pool.gaugeInfo.gaugeDex == GaugeDex.SWAPX) { _claimSwapxRewards(_pid); } } } function claimAllFarmRewards() public onlyOperator { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { claimFarmRewards(pid); } } function _claimShadowRewards(uint256 _pid) internal { PoolInfo storage pool = poolInfo[_pid]; address[] memory gaugeRewardTokens = IShadowGauge(pool.gaugeInfo.gauge).rewardsList(); IShadowGauge(pool.gaugeInfo.gauge).getReward(address(this), gaugeRewardTokens); for (uint256 i = 0; i < gaugeRewardTokens.length; i++) { IERC20 rewardToken = IERC20(gaugeRewardTokens[i]); uint256 rewardAmount = rewardToken.balanceOf(address(this)); if (rewardAmount > 0) { if (address(rewardToken) == XSHADOW_TOKEN) { if (mustConvertXSHADOW == true) { _convertXShadow(rewardAmount); } } else { rewardToken.safeTransfer(devFund, rewardAmount); } } } } function _convertXShadow(uint256 _amount) internal { IERC20(XSHADOW_TOKEN).approve(address(X33_TOKEN), _amount); // approve xshadow to x33 bool canMint = IX33(X33_TOKEN).isUnlocked(); if (canMint) { uint256 x33ReceivedAmount = IERC4626(X33_TOKEN).deposit(_amount, address(this)); // mint x33 IERC20(X33_TOKEN).safeTransfer(devFund, x33ReceivedAmount); // send x33 to devFund } } function convertXShadowManual(uint256 _amount) public onlyOperator { IERC20(XSHADOW_TOKEN).approve(address(X33_TOKEN), _amount); // approve xshadow to x33 bool canMint = IX33(X33_TOKEN).isUnlocked(); if (canMint) { IERC4626(X33_TOKEN).deposit(_amount, address(this)); // mint x33 IERC20(X33_TOKEN).safeTransfer(devFund, _amount); // send x33 to devFund } } function _claimSwapxRewards(uint256 _pid) internal { PoolInfo storage pool = poolInfo[_pid]; ISwapxGauge(pool.gaugeInfo.gauge).getReward(); // claim the swapx rewards IERC20 rewardToken = IERC20(SWAPX_TOKEN); uint256 rewardAmount = rewardToken.balanceOf(address(this)); if (rewardAmount > 0) { rewardToken.safeTransfer(devFund, rewardAmount); } } // Add a gauge to a pool function enableGauge(uint256 _pid, GaugeDex _gaugeDex) public onlyOperator { if (_gaugeDex == GaugeDex.SHADOW) { _enableGaugeShadow(_pid); } if (_gaugeDex == GaugeDex.SWAPX) { _enableGaugeSwapX(_pid); } } function _enableGaugeShadow(uint256 _pid) internal { address gauge = shadowVoter.gaugeForPool(address(poolInfo[_pid].token)); if (gauge != address(0)) { poolInfo[_pid].gaugeInfo = GaugeInfo(true, gauge, GaugeDex.SHADOW); } } function _enableGaugeSwapX(uint256 _pid) internal { // Add the logic for swapx address gauge = swapxVoter.gauges(address(poolInfo[_pid].token)); if (gauge != address(0)) { poolInfo[_pid].gaugeInfo = GaugeInfo(true, gauge, GaugeDex.SWAPX); } } // Withdraw LP from the gauge function withdrawFromGauge(uint256 _pid, uint256 _amount) internal { PoolInfo storage pool = poolInfo[_pid]; // Do nothing if this pool doesn't have a gauge if (pool.gaugeInfo.isGauge) { // Withdraw from the gauge IShadowGauge(pool.gaugeInfo.gauge).withdraw(_amount); } } // Deposit LP tokens. function deposit(uint256 _pid, uint256 _amount) public nonReentrant { address _sender = msg.sender; PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_sender]; updatePool(_pid); if (user.amount > 0) { uint256 _pending = user.amount.mul(pool.accGmatrixPerShare).div(1e18).sub(user.rewardDebt); if (_pending > 0) { safeGmatrixTransfer(_sender, _pending); emit RewardPaid(_sender, _pending); } } if (_amount > 0 ) { pool.token.safeTransferFrom(_sender, address(this), _amount); uint256 depositDebt = _amount.mul(pool.depFee).div(10000); user.amount = user.amount.add(_amount.sub(depositDebt)); pool.token.safeTransfer(devFund, depositDebt); } updatePoolWithGaugeDeposit(_pid); user.rewardDebt = user.amount.mul(pool.accGmatrixPerShare).div(1e18); emit Deposit(_sender, _pid, _amount); } // Withdraw LP tokens. function withdraw(uint256 _pid, uint256 _amount) public nonReentrant { address _sender = msg.sender; PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_sender]; require(user.amount >= _amount, "withdraw: not good"); updatePool(_pid); updatePoolWithGaugeDeposit(_pid); uint256 _pending = user.amount.mul(pool.accGmatrixPerShare).div(1e18).sub(user.rewardDebt); if (_pending > 0) { safeGmatrixTransfer(_sender, _pending); emit RewardPaid(_sender, _pending); } if (_amount > 0) { user.amount = user.amount.sub(_amount); withdrawFromGauge(_pid, _amount); pool.token.safeTransfer(_sender, _amount); } user.rewardDebt = user.amount.mul(pool.accGmatrixPerShare).div(1e18); emit Withdraw(_sender, _pid, _amount); } // Withdraw without caring about rewards. EMERGENCY ONLY. function emergencyWithdraw(uint256 _pid) public nonReentrant { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; uint256 _amount = user.amount; withdrawFromGauge(_pid, _amount); user.amount = 0; user.rewardDebt = 0; pool.token.safeTransfer(msg.sender, _amount); emit EmergencyWithdraw(msg.sender, _pid, _amount); } // Safe gmatrix transfer function, just in case if rounding error causes pool to not have enough GMATRIXs. function safeGmatrixTransfer(address _to, uint256 _amount) internal { uint256 _gmatrixBal = gmatrix.balanceOf(address(this)); if (_gmatrixBal > 0) { if (_amount > _gmatrixBal) { gmatrix.safeTransfer(_to, _gmatrixBal); } else { gmatrix.safeTransfer(_to, _amount); } } } function setOperator(address _operator) external onlyOperator { operator = _operator; } function setDevFund(address _devFund) public onlyOperator { devFund = _devFund; } function setMustConvertXSHADOW(bool _mustConvertXSHADOW) external onlyOperator { mustConvertXSHADOW = _mustConvertXSHADOW; } function setClaimGaugeRewardsOnUpdatePool(bool _claimGaugeRewardsOnUpdatePool) external onlyOperator { claimGaugeRewardsOnUpdatePool = _claimGaugeRewardsOnUpdatePool; } function governanceRecoverUnsupported(IERC20 _token, uint256 amount, address to) external onlyOperator { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { PoolInfo storage pool = poolInfo[pid]; require(_token != pool.token, "ShareRewardPool: Token cannot be pool token"); } _token.safeTransfer(to, amount); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ 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)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ 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"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // 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 cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol) 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 generally not needed starting with Solidity 0.8, since 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 subtraction 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: MIT // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC4626.sol) pragma solidity ^0.8.20; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; /** * @dev Interface of the ERC-4626 "Tokenized Vault Standard", as defined in * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626]. */ interface IERC4626 is IERC20, IERC20Metadata { event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); event Withdraw( address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares ); /** * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. * * - MUST be an ERC-20 token contract. * - MUST NOT revert. */ function asset() external view returns (address assetTokenAddress); /** * @dev Returns the total amount of the underlying asset that is “managed” by Vault. * * - SHOULD include any compounding that occurs from yield. * - MUST be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT revert. */ function totalAssets() external view returns (uint256 totalManagedAssets); /** * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToShares(uint256 assets) external view returns (uint256 shares); /** * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToAssets(uint256 shares) external view returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, * through a deposit call. * * - MUST return a limited value if receiver is subject to some deposit limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. * - MUST NOT revert. */ function maxDeposit(address receiver) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given * current on-chain conditions. * * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit * call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called * in the same transaction. * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the * deposit would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewDeposit(uint256 assets) external view returns (uint256 shares); /** * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * deposit execution, and are accounted for during deposit. * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function deposit(uint256 assets, address receiver) external returns (uint256 shares); /** * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. * - MUST return a limited value if receiver is subject to some mint limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. * - MUST NOT revert. */ function maxMint(address receiver) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given * current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call * in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the * same transaction. * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint * would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by minting. */ function previewMint(uint256 shares) external view returns (uint256 assets); /** * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint * execution, and are accounted for during mint. * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function mint(uint256 shares, address receiver) external returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the * Vault, through a withdraw call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST NOT revert. */ function maxWithdraw(address owner) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, * given current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw * call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if * called * in the same transaction. * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though * the withdrawal would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewWithdraw(uint256 assets) external view returns (uint256 shares); /** * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * withdraw execution, and are accounted for during withdraw. * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); /** * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, * through a redeem call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. * - MUST NOT revert. */ function maxRedeem(address owner) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, * given current on-chain conditions. * * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call * in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the * same transaction. * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the * redemption would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by redeeming. */ function previewRedeem(uint256 shares) external view returns (uint256 assets); /** * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * redeem execution, and are accounted for during redeem. * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.26; interface IShadowGauge { error ZERO_AMOUNT(); error CANT_NOTIFY_STAKE(); error REWARD_TOO_HIGH(); error NOT_GREATER_THAN_REMAINING(uint256 amount, uint256 remaining); error TOKEN_ERROR(address token); error NOT_WHITELISTED(); error NOT_AUTHORIZED(); event Deposit(address indexed from, uint256 amount); event Withdraw(address indexed from, uint256 amount); event NotifyReward( address indexed from, address indexed reward, uint256 amount ); event ClaimRewards( address indexed from, address indexed reward, uint256 amount ); event RewardWhitelisted(address indexed reward, bool whitelisted); /// @notice Get the amount of stakingToken deposited by an account function balanceOf(address) external view returns (uint256); /// @notice returns an array with all the addresses of the rewards /// @return _rewards array of addresses for rewards function rewardsList() external view returns (address[] memory _rewards); /// @notice number of different rewards the gauge has facilitated that are 'active' /// @return _length the number of individual rewards function rewardsListLength() external view returns (uint256 _length); /// @notice returns the last time the reward was modified or periodFinish if the reward has ended /// @param token address of the token /// @return ltra last time reward applicable function lastTimeRewardApplicable( address token ) external view returns (uint256 ltra); /// @notice displays the data struct of rewards for a token /// @param token the address of the token /// @return data rewards struct function rewardData( address token ) external view returns (Reward memory data); /// @notice calculates the amount of tokens earned for an address /// @param token address of the token to check /// @param account address to check /// @return _reward amount of token claimable function earned( address token, address account ) external view returns (uint256 _reward); /// @notice claims rewards (shadow + any external LP Incentives) /// @param account the address to claim for /// @param tokens an array of the tokens to claim function getReward(address account, address[] calldata tokens) external; /// @notice claims all rewards and instant exits xshadow into shadow function getRewardAndExit( address account, address[] calldata tokens ) external; /// @notice calculates the token amounts earned per lp token /// @param token address of the token to check /// @return rpt reward per token function rewardPerToken(address token) external view returns (uint256 rpt); /// @notice deposit all LP tokens from msg.sender's wallet to the gauge function depositAll() external; /// @param recipient the address of who to deposit on behalf of /// @param amount the amount of LP tokens to withdraw function depositFor(address recipient, uint256 amount) external; /// @notice deposit LP tokens to the gauge /// @param amount the amount of LP tokens to withdraw function deposit(uint256 amount) external; /// @notice withdraws all fungible LP tokens from legacy gauges function withdrawAll() external; /// @notice withdraws fungible LP tokens from legacy gauges /// @param amount the amount of LP tokens to withdraw function withdraw(uint256 amount) external; /// @notice calculates how many tokens are left to be distributed /// @dev reduces per second /// @param token the address of the token function left(address token) external view returns (uint256); /// @notice add a reward to the whitelist /// @param _reward address of the reward function whitelistReward(address _reward) external; /// @notice remove rewards from the whitelist /// @param _reward address of the reward function removeRewardWhitelist(address _reward) external; /** * @notice amount must be greater than left() for the token, this is to prevent griefing attacks * @notice notifying rewards is completely permissionless * @notice if nobody registers for a newly added reward for the period it will remain in the contract indefinitely */ function notifyRewardAmount(address token, uint256 amount) external; struct Reward { /// @dev tokens per second uint256 rewardRate; /// @dev 7 days after start uint256 periodFinish; uint256 lastUpdateTime; uint256 rewardPerTokenStored; } /// @notice checks if a reward is whitelisted /// @param reward the address of the reward /// @return true if the reward is whitelisted, false otherwise function isWhitelisted(address reward) external view returns (bool); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.26; pragma abicoder v2; interface IShadowVoter { error ACTIVE_GAUGE(address gauge); error GAUGE_INACTIVE(address gauge); error ALREADY_WHITELISTED(address token); error NOT_AUTHORIZED(address caller); error NOT_WHITELISTED(); error NOT_POOL(); error NOT_INIT(); error LENGTH_MISMATCH(); error NO_GAUGE(); error ALREADY_DISTRIBUTED(address gauge, uint256 period); error ZERO_VOTE(address pool); error RATIO_TOO_HIGH(uint256 _xRatio); error VOTE_UNSUCCESSFUL(); event GaugeCreated( address indexed gauge, address creator, address feeDistributor, address indexed pool ); event GaugeKilled(address indexed gauge); event GaugeRevived(address indexed gauge); event Voted(address indexed owner, uint256 weight, address indexed pool); event Abstained(address indexed owner, uint256 weight); event Deposit( address indexed lp, address indexed gauge, address indexed owner, uint256 amount ); event Withdraw( address indexed lp, address indexed gauge, address indexed owner, uint256 amount ); event NotifyReward( address indexed sender, address indexed reward, uint256 amount ); event DistributeReward( address indexed sender, address indexed gauge, uint256 amount ); event EmissionsRatio( address indexed caller, uint256 oldRatio, uint256 newRatio ); event NewGovernor(address indexed sender, address indexed governor); event Whitelisted(address indexed whitelister, address indexed token); event WhitelistRevoked( address indexed forbidder, address indexed token, bool status ); event MainTickSpacingChanged( address indexed token0, address indexed token1, int24 indexed newMainTickSpacing ); event Poke(address indexed user); function initialize( address _shadow, address _legacyFactory, address _gauges, address _feeDistributorFactory, address _minter, address _msig, address _xShadow, address _clFactory, address _clGaugeFactory, address _nfpManager, address _feeRecipientFactory, address _voteModule, address _launcherPlugin ) external; /// @notice denominator basis function BASIS() external view returns (uint256); /// @notice ratio of xShadow emissions globally function xRatio() external view returns (uint256); /// @notice xShadow contract address function xShadow() external view returns (address); /// @notice legacy factory address (uni-v2/stableswap) function legacyFactory() external view returns (address); /// @notice concentrated liquidity factory function clFactory() external view returns (address); /// @notice gauge factory for CL function clGaugeFactory() external view returns (address); /// @notice legacy fee recipient factory function feeRecipientFactory() external view returns (address); /// @notice peripheral NFPManager contract function nfpManager() external view returns (address); /// @notice returns the address of the current governor /// @return _governor address of the governor function governor() external view returns (address _governor); /// @notice the address of the vote module /// @return _voteModule the vote module contract address function voteModule() external view returns (address _voteModule); /// @notice address of the central access Hub function accessHub() external view returns (address); /// @notice the address of the shadow launcher plugin to enable third party launchers /// @return _launcherPlugin the address of the plugin function launcherPlugin() external view returns (address _launcherPlugin); /// @notice distributes emissions from the minter to the voter /// @param amount the amount of tokens to notify function notifyRewardAmount(uint256 amount) external; /// @notice distributes the emissions for a specific gauge /// @param _gauge the gauge address function distribute(address _gauge) external; /// @notice returns the address of the gauge factory /// @param _gaugeFactory gauge factory address function gaugeFactory() external view returns (address _gaugeFactory); /// @notice returns the address of the feeDistributor factory /// @return _feeDistributorFactory feeDist factory address function feeDistributorFactory() external view returns (address _feeDistributorFactory); /// @notice returns the address of the minter contract /// @return _minter address of the minter function minter() external view returns (address _minter); /// @notice check if the gauge is active for governance use /// @param _gauge address of the gauge /// @return _trueOrFalse if the gauge is alive function isAlive(address _gauge) external view returns (bool _trueOrFalse); /// @notice allows the token to be paired with other whitelisted assets to participate in governance /// @param _token the address of the token function whitelist(address _token) external; /// @notice effectively disqualifies a token from governance /// @param _token the address of the token function revokeWhitelist(address _token) external; /// @notice returns if the address is a gauge /// @param gauge address of the gauge /// @return _trueOrFalse boolean if the address is a gauge function isGauge(address gauge) external view returns (bool _trueOrFalse); /// @notice disable a gauge from governance /// @param _gauge address of the gauge function killGauge(address _gauge) external; /// @notice re-activate a dead gauge /// @param _gauge address of the gauge function reviveGauge(address _gauge) external; /// @notice re-cast a tokenID's votes /// @param owner address of the owner function poke(address owner) external; /// @notice sets the main tickspacing of a token pairing /// @param tokenA address of tokenA /// @param tokenB address of tokenB /// @param tickSpacing the main tickspacing to set to function setMainTickSpacing( address tokenA, address tokenB, int24 tickSpacing ) external; /// @notice returns if the address is a fee distributor /// @param _feeDistributor address of the feeDist /// @return _trueOrFalse if the address is a fee distributor function isFeeDistributor( address _feeDistributor ) external view returns (bool _trueOrFalse); /// @notice returns the address of the emission's token /// @return _shadow emissions token contract address function shadow() external view returns (address _shadow); /// @notice returns the address of the pool's gauge, if any /// @param _pool pool address /// @return _gauge gauge address function gaugeForPool(address _pool) external view returns (address _gauge); /// @notice returns the address of the pool's feeDistributor, if any /// @param _gauge address of the gauge /// @return _feeDistributor address of the pool's feedist function feeDistributorForGauge( address _gauge ) external view returns (address _feeDistributor); /// @notice returns the new toPool that was redirected fromPool /// @param fromPool address of the original pool /// @return toPool the address of the redirected pool function poolRedirect( address fromPool ) external view returns (address toPool); /// @notice returns the gauge address of a CL pool /// @param tokenA address of token A in the pair /// @param tokenB address of token B in the pair /// @param tickSpacing tickspacing of the pool /// @return gauge address of the gauge function gaugeForClPool( address tokenA, address tokenB, int24 tickSpacing ) external view returns (address gauge); /// @notice returns the array of all tickspacings for the tokenA/tokenB combination /// @param tokenA address of token A in the pair /// @param tokenB address of token B in the pair /// @return _ts array of all the tickspacings function tickSpacingsForPair( address tokenA, address tokenB ) external view returns (int24[] memory _ts); /// @notice returns the main tickspacing used in the gauge/governance process /// @param tokenA address of token A in the pair /// @param tokenB address of token B in the pair /// @return _ts the main tickspacing function mainTickSpacingForPair( address tokenA, address tokenB ) external view returns (int24 _ts); /// @notice returns the block.timestamp divided by 1 week in seconds /// @return period the period used for gauges function getPeriod() external view returns (uint256 period); /// @notice cast a vote to direct emissions to gauges and earn incentives /// @param owner address of the owner /// @param _pools the list of pools to vote on /// @param _weights an arbitrary weight per pool which will be normalized to 100% regardless of numerical inputs function vote( address owner, address[] calldata _pools, uint256[] calldata _weights ) external; /// @notice reset the vote of an address /// @param owner address of the owner function reset(address owner) external; /// @notice set the governor address /// @param _governor the new governor address function setGovernor(address _governor) external; /// @notice recover stuck emissions /// @param _gauge the gauge address /// @param _period the period function stuckEmissionsRecovery(address _gauge, uint256 _period) external; /// @notice whitelists extra rewards for a gauge /// @param _gauge the gauge to whitelist rewards to /// @param _reward the reward to whitelist function whitelistGaugeRewards(address _gauge, address _reward) external; /// @notice removes a reward from the gauge whitelist /// @param _gauge the gauge to remove the whitelist from /// @param _reward the reward to remove from the whitelist function removeGaugeRewardWhitelist( address _gauge, address _reward ) external; /// @notice creates a legacy gauge for the pool /// @param _pool pool's address /// @return _gauge address of the new gauge function createGauge(address _pool) external returns (address _gauge); /// @notice create a concentrated liquidity gauge /// @param tokenA the address of tokenA /// @param tokenB the address of tokenB /// @param tickSpacing the tickspacing of the pool /// @return _clGauge address of the new gauge function createCLGauge( address tokenA, address tokenB, int24 tickSpacing ) external returns (address _clGauge); /// @notice claim concentrated liquidity gauge rewards for specific NFP token ids /// @param _gauges array of gauges /// @param _tokens two dimensional array for the tokens to claim /// @param _nfpTokenIds two dimensional array for the NFPs function claimClGaugeRewards( address[] calldata _gauges, address[][] calldata _tokens, uint256[][] calldata _nfpTokenIds ) external; /// @notice claim arbitrary rewards from specific feeDists /// @param owner address of the owner /// @param _feeDistributors address of the feeDists /// @param _tokens two dimensional array for the tokens to claim function claimIncentives( address owner, address[] calldata _feeDistributors, address[][] calldata _tokens ) external; /// @notice claim arbitrary rewards from specific gauges /// @param _gauges address of the gauges /// @param _tokens two dimensional array for the tokens to claim function claimRewards( address[] calldata _gauges, address[][] calldata _tokens ) external; /// @notice claim arbitrary rewards from specific legacy gauges, and exit to shadow /// @param _gauges address of the gauges /// @param _tokens two dimensional array for the tokens to claim function claimLegacyRewardsAndExit( address[] calldata _gauges, address[][] calldata _tokens ) external; /// @notice distribute emissions to a gauge for a specific period /// @param _gauge address of the gauge /// @param _period value of the period function distributeForPeriod(address _gauge, uint256 _period) external; /// @notice attempt distribution of emissions to all gauges function distributeAll() external; /// @notice distribute emissions to gauges by index /// @param startIndex start of the loop /// @param endIndex end of the loop function batchDistributeByIndex( uint256 startIndex, uint256 endIndex ) external; /// @notice returns the votes cast for a tokenID /// @param owner address of the owner /// @return votes an array of votes casted /// @return weights an array of the weights casted per pool function getVotes( address owner, uint256 period ) external view returns (address[] memory votes, uint256[] memory weights); /// @notice returns an array of all the gauges /// @return _gauges the array of gauges function getAllGauges() external view returns (address[] memory _gauges); /// @notice returns an array of all the feeDists /// @return _feeDistributors the array of feeDists function getAllFeeDistributors() external view returns (address[] memory _feeDistributors); /// @notice sets the xShadowRatio default function setGlobalRatio(uint256 _xRatio) external; /// @notice whether the token is whitelisted in governance function isWhitelisted(address _token) external view returns (bool _tf); /// @notice function for removing malicious or stuffed tokens function removeFeeDistributorReward( address _feeDist, address _token ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface ISwapxGauge { function notifyRewardAmount(address token, uint amount) external; // function getReward(address account, address[] memory tokens) external; function getReward(address account) external; function getReward() external; function deposit(uint256 amount) external; function withdraw(uint256 amount) external; function claimFees() external returns (uint claimed0, uint claimed1); function left(address token) external view returns (uint); function rewardRate(address _pair) external view returns (uint); function balanceOf(address _account) external view returns (uint); function isForPair() external view returns (bool); function totalSupply() external view returns (uint); function earned(address token, address account) external view returns (uint); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.26; pragma abicoder v2; interface ISwapxVoter { function gauges(address _pool) external view returns (address); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.24; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface IX33 is IERC20 { /// @dev parameters passed to the aggregator swap struct AggregatorParams { address aggregator; // address of the whitelisted aggregator address tokenIn; // token to swap from uint256 amountIn; // amount of tokenIn to swap uint256 minAmountOut; // minimum amount of tokenOut to receive bytes callData; // encoded swap calldata } /** * Error strings */ error ZERO(); error NOT_ENOUGH(); error NOT_CONFORMED_TO_SCALE(uint256); error NOT_ACCESSHUB(address); error LOCKED(); error REBASE_IN_PROGRESS(); error AGGREGATOR_REVERTED(bytes); error AMOUNT_OUT_TOO_LOW(uint256); error AGGREGATOR_NOT_WHITELISTED(address); error FORBIDDEN_TOKEN(address); event Entered(address indexed user, uint256 amount, uint256 ratioAtDeposit); event Exited(address indexed user, uint256 _outAmount, uint256 ratioAtWithdrawal); event NewOperator(address _oldOperator, address _newOperator); event Compounded(uint256 oldRatio, uint256 newRatio, uint256 amount); event SwappedBribe(address indexed operator, address indexed tokenIn, uint256 amountIn, uint256 amountOut); event Rebased(uint256 oldRatio, uint256 newRatio, uint256 amount); /// @notice Event emitted when an aggregator's whitelist status changes event AggregatorWhitelistUpdated(address aggregator, bool status); event Unlocked(uint256 _ts); event UpdatedIndex(uint256 _index); event ClaimedIncentives(address[] feeDistributors, address[][] tokens); /// @notice submits the optimized votes for the epoch function submitVotes(address[] calldata _pools, uint256[] calldata _weights) external; /// @notice swap function using aggregators to process rewards into SHADOW function swapIncentiveViaAggregator(AggregatorParams calldata _params) external; /// @notice claims the rebase accrued to x33 function claimRebase() external; /// @notice compounds any existing SHADOW within the contract function compound() external; /// @notice direct claim function claimIncentives(address[] calldata _feeDistributors, address[][] calldata _tokens) external; /// @notice rescue stuck tokens function rescue(address _token, uint256 _amount) external; /// @notice allows the operator to unlock the contract for the current period function unlock() external; /// @notice add or remove an aggregator from the whitelist (timelocked) /// @param _aggregator address of the aggregator to update /// @param _status new whitelist status function whitelistAggregator(address _aggregator, bool _status) external; /// @notice transfers the operator via accesshub function transferOperator(address _newOperator) external; /// @notice simple getPeriod call function getPeriod() external view returns (uint256 period); /// @notice if the contract is unlocked for deposits function isUnlocked() external view returns (bool); /// @notice determines whether the cooldown is active function isCooldownActive() external view returns (bool); /// @notice address of the current operator function operator() external view returns (address); /// @notice accessHub address function accessHub() external view returns (address); /// @notice returns the ratio of xShadow per X33 token function ratio() external view returns (uint256 _ratio); /// @notice the most recent active period the contract has interacted in function activePeriod() external view returns (uint256); /// @notice whether the periods are unlocked function periodUnlockStatus(uint256 _period) external view returns (bool unlocked); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IBasisAsset { function mint(address recipient, uint256 amount) external returns (bool); function burn(uint256 amount) external; function burnFrom(address from, uint256 amount) external; function isOperator() external returns (bool); function operator() external view returns (address); function transferOperator(address newOperator_) external; }
{ "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_gmatrix","type":"address"},{"internalType":"address","name":"_devFund","type":"address"},{"internalType":"uint256","name":"_poolStartTime","type":"uint256"},{"internalType":"address","name":"_shadowVoter","type":"address"},{"internalType":"address","name":"_swapxVoter","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"SWAPX_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"X33_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"XSHADOW_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"uint256","name":"_depFee","type":"uint256"},{"internalType":"contract IERC20","name":"_token","type":"address"},{"internalType":"bool","name":"_withUpdate","type":"bool"},{"internalType":"uint256","name":"_lastRewardTime","type":"uint256"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_pids","type":"uint256[]"},{"internalType":"uint256[]","name":"_allocPoints","type":"uint256[]"},{"internalType":"uint256[]","name":"_depFees","type":"uint256[]"}],"name":"bulkSet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimAllFarmRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"claimFarmRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimGaugeRewardsOnUpdatePool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"convertXShadowManual","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"devFund","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"enum GMatrixRewardPool.GaugeDex","name":"_gaugeDex","type":"uint8"}],"name":"enableGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fromTime","type":"uint256"},{"internalType":"uint256","name":"_toTime","type":"uint256"}],"name":"getGeneratedReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gmatrix","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"governanceRecoverUnsupported","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"massUpdatePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fromPid","type":"uint256"},{"internalType":"uint256","name":"_toPid","type":"uint256"}],"name":"massUpdatePoolsInRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mustConvertXSHADOW","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolEndTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolInfo","outputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"depFee","type":"uint256"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"lastRewardTime","type":"uint256"},{"internalType":"uint256","name":"accGmatrixPerShare","type":"uint256"},{"internalType":"bool","name":"isStarted","type":"bool"},{"components":[{"internalType":"bool","name":"isGauge","type":"bool"},{"internalType":"address","name":"gauge","type":"address"},{"internalType":"enum GMatrixRewardPool.GaugeDex","name":"gaugeDex","type":"uint8"}],"internalType":"struct GMatrixRewardPool.GaugeInfo","name":"gaugeInfo","type":"tuple"},{"internalType":"uint256","name":"poolGmatrixPerSec","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"runningTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"uint256","name":"_depFee","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_claimGaugeRewardsOnUpdatePool","type":"bool"}],"name":"setClaimGaugeRewardsOnUpdatePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_devFund","type":"address"}],"name":"setDevFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_mustConvertXSHADOW","type":"bool"}],"name":"setMustConvertXSHADOW","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"setOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shadowVoter","outputs":[{"internalType":"contract IShadowVoter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sharePerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swapxVoter","outputs":[{"internalType":"contract ISwapxVoter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAllocPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"updatePoolWithGaugeDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"rewardDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040526002805461ffff60a01b191661010160a01b17905560006008819055600b556301e13380600c5534801561003757600080fd5b506040516144c83803806144c8833981016040819052610056916112df565b60016000554283116100af5760405162461bcd60e51b815260206004820181905260248201527f706f6f6c2063616e74206265207374617274656420696e20746865207061737460448201526064015b60405180910390fd5b6001600160a01b038516156100da57600280546001600160a01b0319166001600160a01b0387161790555b6001600160a01b0384161561010557600580546001600160a01b0319166001600160a01b0386161790555b6009839055600c546101179084611354565b600a5560018054336001600160a01b0319918216179091556003805482166001600160a01b0385811691909117909155600480548316848316179055600580549092169086161790556101826000807337c4c5e345ae4d4041b7f519343f942716fc6fe681806101ae565b6101a4600080736be3c7ef769fd208923105b048b31c547301c81a81806101ae565b50505050506115d8565b6001546001600160a01b0316331461020c5760405162461bcd60e51b815260206004820152602d60248201526000805160206144a883398151915260448201526c103a34329037b832b930ba37b960991b60648201526084016100a6565b61021583610427565b8115610223576102236104d0565b600954421015610252578060000361023e5750600954610266565b60095481101561024d57506009545b610266565b80158061025e57504281105b156102665750425b6000600954821115806102795750428211155b90506006604051806101000160405280866001600160a01b03168152602001878152602001888152602001848152602001600081526020018315158152602001604051806060016040528060001515815260200160006001600160a01b03168152602001600060028111156102f0576102f0611367565b905281526020908101899052825460018181018555600094855293829020835160089092020180546001600160a01b039283166001600160a01b03199091161781558383015194810194909455604080840151600280870191909155606085015160038701556080850151600487015560a085015160058701805491151560ff1990921691909117905560c085015180516006880180549683015190951661010002610100600160a81b0319911515919091166001600160a81b031990961695909517949094178084559184015194959491839160ff60a81b1990911690600160a81b9084908111156103e5576103e5611367565b0217905550505060e082015181600701555050801561041f5760085461040b90876104fc565b600855600b5461041b90876104fc565b600b555b505050505050565b60065460005b818110156104cb57826001600160a01b0316600682815481106104525761045261137d565b60009182526020909120600890910201546001600160a01b0316036104c35760405162461bcd60e51b815260206004820152602160248201527f474d6174726978526577617264506f6f6c3a206578697374696e6720706f6f6c6044820152603f60f81b60648201526084016100a6565b60010161042d565b505050565b60065460005b818110156104f8576104e781610511565b6104f08161072c565b6001016104d6565b5050565b60006105088284611354565b90505b92915050565b61051a8161072c565b60006006828154811061052f5761052f61137d565b906000526020600020906008020190508060030154421161054e575050565b600681015460009060ff166105cd5781546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156105a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c89190611393565b61063f565b60068201546040516370a0823160e01b81523060048201526101009091046001600160a01b0316906370a0823190602401602060405180830381865afa15801561061b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063f9190611393565b90508060000361065457504260039091015550565b600582015460ff166106985760058201805460ff191660011790556002820154600854610680916104fc565b6008556007820154600b54610694916104fc565b600b555b6008541561070b5760006106b683600301544261094160201b60201c565b905060006106dd6008546106d78660020154856109f060201b90919060201c565b906109fc565b90506107036106f8846106d784670de0b6b3a76400006109f0565b6004860154906104fc565b600485015550505b426003830155600254600160a01b900460ff16156104cb576104cb83610a08565b6000600682815481106107415761074161137d565b60009182526020822060089190910201600681015481546040516370a0823160e01b81523060048201529294506101009091046001600160a01b0390811693929116906370a0823190602401602060405180830381865afa1580156107aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ce9190611393565b600684015490915060ff161561093b57801561093b578254604051636eb1769f60e11b81523060048201526001600160a01b0384811660248301528392169063dd62ed3e90604401602060405180830381865afa158015610833573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108579190611393565b10156108d657825460405163095ea7b360e01b81526001600160a01b03848116600483015260001960248301529091169063095ea7b3906044016020604051808303816000875af11580156108b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d491906113ac565b505b600683015460405163b6b55f2560e01b8152600481018390526101009091046001600160a01b03169063b6b55f2590602401600060405180830381600087803b15801561092257600080fd5b505af1158015610936573d6000803e3d6000fd5b505050505b50505050565b60008183106109525750600061050b565b600a5482106109af57600a54831061096c5750600061050b565b600954831161099a57600b54600954600a54610993929161098d9190610afb565b906109f0565b905061050b565b600b54600a54610993919061098d9086610afb565b60095482116109c05750600061050b565b60095483116109df57600b54600954610993919061098d908590610afb565b600b546109939061098d8486610afb565b600061050882846113d5565b600061050882846113ec565b6001546001600160a01b03163314610a665760405162461bcd60e51b815260206004820152602d60248201526000805160206144a883398151915260448201526c103a34329037b832b930ba37b960991b60648201526084016100a6565b600060068281548110610a7b57610a7b61137d565b60009182526020909120600890910201600681015490915060ff16156104f85760016006820154600160a81b900460ff166002811115610abd57610abd611367565b03610acb57610acb82610b07565b60026006820154600160a81b900460ff166002811115610aed57610aed611367565b036104f8576104f882610d28565b6000610508828461140e565b600060068281548110610b1c57610b1c61137d565b9060005260206000209060080201905060008160060160000160019054906101000a90046001600160a01b03166001600160a01b0316638003b6146040518163ffffffff1660e01b8152600401600060405180830381865afa158015610b86573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610bae9190810190611437565b60068301546040516331279d3d60e01b815291925061010090046001600160a01b0316906331279d3d90610be89030908590600401611506565b600060405180830381600087803b158015610c0257600080fd5b505af1158015610c16573d6000803e3d6000fd5b5050505060005b815181101561093b576000828281518110610c3a57610c3a61137d565b60209081029190910101516040516370a0823160e01b81523060048201529091506000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610c8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb39190611393565b90508015610d1e57735050bc082ff4a74fb6b0b04385defddb114b2423196001600160a01b03831601610d0457600254600160a81b900460ff161515600103610cff57610cff81610e54565b610d1e565b600554610d1e906001600160a01b0384811691168361100f565b5050600101610c1d565b600060068281548110610d3d57610d3d61137d565b906000526020600020906008020190508060060160000160019054906101000a90046001600160a01b03166001600160a01b0316633d18b9126040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610da257600080fd5b505af1158015610db6573d6000803e3d6000fd5b50506040516370a0823160e01b815230600482015273a04bc7140c26fc9bb1f36b1a604c7a5a88fb0e7092506000915082906370a0823190602401602060405180830381865afa158015610e0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e329190611393565b9050801561093b5760055461093b906001600160a01b0384811691168361100f565b60405163095ea7b360e01b8152733333111a391cc08fa51353e9195526a70b333333600482015260248101829052735050bc082ff4a74fb6b0b04385defddb114b24249063095ea7b3906044016020604051808303816000875af1158015610ec0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee491906113ac565b506000733333111a391cc08fa51353e9195526a70b3333336001600160a01b0316638380edb76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5d91906113ac565b905080156104f857604051636e553f6560e01b815260048101839052306024820152600090733333111a391cc08fa51353e9195526a70b33333390636e553f65906044016020604051808303816000875af1158015610fc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe49190611393565b6005549091506104cb90733333111a391cc08fa51353e9195526a70b333333906001600160a01b0316835b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663a9059cbb60e01b179091526104cb91859161106516565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908201526000906110b2906001600160a01b038516908490611132565b90508051600014806110d35750808060200190518101906110d391906113ac565b6104cb5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016100a6565b60606111418484600085611149565b949350505050565b6060824710156111aa5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016100a6565b600080866001600160a01b031685876040516111c69190611589565b60006040518083038185875af1925050503d8060008114611203576040519150601f19603f3d011682016040523d82523d6000602084013e611208565b606091505b50909250905061121a87838387611225565b979650505050505050565b6060831561129457825160000361128d576001600160a01b0385163b61128d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016100a6565b5081611141565b61114183838151156112a95781518083602001fd5b8060405162461bcd60e51b81526004016100a691906115a5565b80516001600160a01b03811681146112da57600080fd5b919050565b600080600080600060a086880312156112f757600080fd5b611300866112c3565b945061130e602087016112c3565b60408701519094509250611324606087016112c3565b9150611332608087016112c3565b90509295509295909350565b634e487b7160e01b600052601160045260246000fd5b8082018082111561050b5761050b61133e565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6000602082840312156113a557600080fd5b5051919050565b6000602082840312156113be57600080fd5b815180151581146113ce57600080fd5b9392505050565b808202811582820484141761050b5761050b61133e565b60008261140957634e487b7160e01b600052601260045260246000fd5b500490565b8181038181111561050b5761050b61133e565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561144957600080fd5b81516001600160401b0381111561145f57600080fd5b8201601f8101841361147057600080fd5b80516001600160401b0381111561148957611489611421565b604051600582901b90603f8201601f191681016001600160401b03811182821017156114b7576114b7611421565b6040529182526020818401810192908101878411156114d557600080fd5b6020850194505b838510156114fb576114ed856112c3565b8152602094850194016114dc565b509695505050505050565b6001600160a01b0383168152604060208083018290528351918301829052600091908401906060840190835b818110156115595783516001600160a01b0316835260209384019390920191600101611532565b50909695505050505050565b60005b83811015611580578181015183820152602001611568565b50506000910152565b6000825161159b818460208701611565565b9190910192915050565b60208152600082518060208401526115c4816040850160208701611565565b601f01601f19169190910160400192915050565b612ec1806115e76000396000f3fe608060405234801561001057600080fd5b50600436106102315760003560e01c8063570ca73511610130578063943f013d116100b8578063cf4b55cb1161007c578063cf4b55cb146104e9578063dfbffa8c146104fc578063e2bbb15814610517578063f11287341461052a578063fddc298c1461053d57600080fd5b8063943f013d14610494578063ae4db9191461049d578063b3ab15fb146104b0578063b947a88d146104c3578063ce862f17146104d657600080fd5b806363eb0416116100ff57806363eb04161461040b5780636e142c8e1461041e5780636e271dd51461043157806390c5ed6a1461043a57806393f1a40b1461044d57600080fd5b8063570ca735146103de5780635752933a146103f15780635f96dc11146103fa578063630b5ba11461040357600080fd5b80633202f6c1116101be57806343b0e8df1161018257806343b0e8df14610377578063441a3e701461038a5780635312ea8e1461039d57806354575af4146103b0578063549c278a146103c357600080fd5b80633202f6c1146103115780633aa158ee146103245780633afb24f11461032c5780634189fafa146103505780634390d2a81461036457600080fd5b80631526fe27116102055780631526fe27146102a857806317caf6f1146102cf5780631f7cceec146102d8578063231f0c6a146102eb5780632df95ed7146102fe57600080fd5b8062c6b39114610236578063081e3eda1461026e57806308428f6d146102805780630998bb4014610293575b600080fd5b610251735050bc082ff4a74fb6b0b04385defddb114b242481565b6040516001600160a01b0390911681526020015b60405180910390f35b6006545b604051908152602001610265565b600254610251906001600160a01b031681565b6102a66102a136600461283c565b610550565b005b6102bb6102b636600461283c565b61061c565b60405161026598979695949392919061286b565b61027260085481565b6102a66102e636600461283c565b6106db565b6102726102f93660046128f5565b6108bf565b6102a661030c36600461283c565b610984565b600354610251906001600160a01b031681565b6102a6610b99565b60025461034090600160a01b900460ff1681565b6040519015158152602001610265565b60025461034090600160a81b900460ff1681565b600554610251906001600160a01b031681565b6102a6610385366004612917565b610be2565b6102a66103983660046128f5565b610cad565b6102a66103ab36600461283c565b610e90565b6102a66103be366004612958565b610f48565b610251733333111a391cc08fa51353e9195526a70b33333381565b600154610251906001600160a01b031681565b610272600b5481565b61027260095481565b6102a6611037565b6102a66104193660046129a8565b61105f565b600454610251906001600160a01b031681565b610272600a5481565b6102a66104483660046129c5565b6110a7565b61047f61045b366004612a17565b60076020908152600092835260408084209091529082529020805460019091015482565b60408051928352602083019190915201610265565b610272600c5481565b6102a66104ab366004612a47565b6112ec565b6102a66104be366004612a47565b611338565b6102a66104d13660046128f5565b611384565b6102a66104e4366004612a64565b611404565b6102726104f7366004612a17565b611472565b61025173a04bc7140c26fc9bb1f36b1a604c7a5a88fb0e7081565b6102a66105253660046128f5565b611657565b6102a66105383660046129a8565b61182f565b6102a661054b366004612ad9565b611877565b6001546001600160a01b031633146105835760405162461bcd60e51b815260040161057a90612b7f565b60405180910390fd5b60006006828154811061059857610598612bcc565b60009182526020909120600890910201600681015490915060ff16156106185760016006820154600160a81b900460ff1660028111156105da576105da612855565b036105e8576105e882611974565b60026006820154600160a81b900460ff16600281111561060a5761060a612855565b036106185761061882611b95565b5050565b6006818154811061062c57600080fd5b6000918252602091829020600890910201805460018201546002808401546003850154600486015460058701546040805160608101825260068a01805460ff8181161515845261010082046001600160a01b039081169e85019e909e529c909a169c50979a9599949893979286169694959094929391850192600160a81b90920416908111156106be576106be612855565b60028111156106cf576106cf612855565b90525060079091015488565b6001546001600160a01b031633146107055760405162461bcd60e51b815260040161057a90612b7f565b60405163095ea7b360e01b8152733333111a391cc08fa51353e9195526a70b333333600482015260248101829052735050bc082ff4a74fb6b0b04385defddb114b24249063095ea7b3906044016020604051808303816000875af1158015610771573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107959190612be2565b506000733333111a391cc08fa51353e9195526a70b3333336001600160a01b0316638380edb76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080e9190612be2565b9050801561061857604051636e553f6560e01b815260048101839052306024820152733333111a391cc08fa51353e9195526a70b33333390636e553f65906044016020604051808303816000875af115801561086e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108929190612bff565b5060055461061890733333111a391cc08fa51353e9195526a70b333333906001600160a01b031684611cbd565b60008183106108d05750600061097e565b600a54821061093857600a5483106108ea5750600061097e565b600954831161091d57610916600b54610910600954600a54611d2090919063ffffffff16565b90611d33565b905061097e565b610916600b5461091085600a54611d2090919063ffffffff16565b60095482116109495750600061097e565b600954831161096d57610916600b5461091060095485611d2090919063ffffffff16565b600b54610916906109108486611d20565b92915050565b60006006828154811061099957610999612bcc565b60009182526020822060089190910201600681015481546040516370a0823160e01b81523060048201529294506101009091046001600160a01b0390811693929116906370a0823190602401602060405180830381865afa158015610a02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a269190612bff565b600684015490915060ff1615610b93578015610b93578254604051636eb1769f60e11b81523060048201526001600160a01b0384811660248301528392169063dd62ed3e90604401602060405180830381865afa158015610a8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aaf9190612bff565b1015610b2e57825460405163095ea7b360e01b81526001600160a01b03848116600483015260001960248301529091169063095ea7b3906044016020604051808303816000875af1158015610b08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2c9190612be2565b505b600683015460405163b6b55f2560e01b8152600481018390526101009091046001600160a01b03169063b6b55f2590602401600060405180830381600087803b158015610b7a57600080fd5b505af1158015610b8e573d6000803e3d6000fd5b505050505b50505050565b6001546001600160a01b03163314610bc35760405162461bcd60e51b815260040161057a90612b7f565b60065460005b8181101561061857610bda81610550565b600101610bc9565b6001546001600160a01b03163314610c0c5760405162461bcd60e51b815260040161057a90612b7f565b610c14611037565b600060068481548110610c2957610c29612bcc565b9060005260206000209060080201905060c88210610c4657600080fd5b60018101829055600581015460ff1615610c9b57610c7d83610c778360020154600854611d2090919063ffffffff16565b90611d3f565b6008556007810154600b54610c97918591610c7791611d20565b600b555b60028101839055600701919091555050565b610cb5611d4b565b6000339050600060068481548110610ccf57610ccf612bcc565b600091825260208083208784526007825260408085206001600160a01b03881686529092529220805460089092029092019250841115610d465760405162461bcd60e51b81526020600482015260126024820152711dda5d1a191c985dce881b9bdd0819dbdbd960721b604482015260640161057a565b610d4f85611da4565b610d5885610984565b6000610d958260010154610d8f670de0b6b3a7640000610d8987600401548760000154611d3390919063ffffffff16565b90611fb3565b90611d20565b90508015610deb57610da78482611fbf565b836001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e048682604051610de291815260200190565b60405180910390a25b8415610e1f578154610dfd9086611d20565b8255610e09868661206a565b8254610e1f906001600160a01b03168587611cbd565b60048301548254610e3d91670de0b6b3a764000091610d8991611d33565b600183015560405185815286906001600160a01b038616907ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5689060200160405180910390a3505050506106186001600055565b610e98611d4b565b600060068281548110610ead57610ead612bcc565b600091825260208083208584526007825260408085203386529092529220805460089092029092019250610ee1848261206a565b600080835560018301558254610f01906001600160a01b03163383611cbd565b604051818152849033907fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05959060200160405180910390a3505050610f456001600055565b50565b6001546001600160a01b03163314610f725760405162461bcd60e51b815260040161057a90612b7f565b60065460005b8181101561102257600060068281548110610f9557610f95612bcc565b6000918252602090912060089091020180549091506001600160a01b03908116908716036110195760405162461bcd60e51b815260206004820152602b60248201527f5368617265526577617264506f6f6c3a20546f6b656e2063616e6e6f7420626560448201526a103837b7b6103a37b5b2b760a91b606482015260840161057a565b50600101610f78565b50610b936001600160a01b0385168385611cbd565b60065460005b818110156106185761104e81611da4565b61105781610984565b60010161103d565b6001546001600160a01b031633146110895760405162461bcd60e51b815260040161057a90612b7f565b60028054911515600160a01b0260ff60a01b19909216919091179055565b6001546001600160a01b031633146110d15760405162461bcd60e51b815260040161057a90612b7f565b6110da836120ff565b81156110e8576110e8611037565b6009544210156111175780600003611103575060095461112b565b60095481101561111257506009545b61112b565b80158061112357504281105b1561112b5750425b60006009548211158061113e5750428211155b90506006604051806101000160405280866001600160a01b03168152602001878152602001888152602001848152602001600081526020018315158152602001604051806060016040528060001515815260200160006001600160a01b03168152602001600060028111156111b5576111b5612855565b905281526020908101899052825460018181018555600094855293829020835160089092020180546001600160a01b039283166001600160a01b03199091161781558383015194810194909455604080840151600280870191909155606085015160038701556080850151600487015560a085015160058701805491151560ff1990921691909117905560c085015180516006880180549683015190951661010002610100600160a81b0319911515919091166001600160a81b031990961695909517949094178084559184015194959491839160ff60a81b1990911690600160a81b9084908111156112aa576112aa612855565b0217905550505060e08201518160070155505080156112e4576008546112d09087611d3f565b600855600b546112e09087611d3f565b600b555b505050505050565b6001546001600160a01b031633146113165760405162461bcd60e51b815260040161057a90612b7f565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633146113625760405162461bcd60e51b815260040161057a90612b7f565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b808211156113d45760405162461bcd60e51b815260206004820181905260248201527f474d6174726978526577617264506f6f6c3a20696e76616c69642072616e6765604482015260640161057a565b815b8181116113ff576113e681611da4565b6113ef81610984565b6113f881612c2e565b90506113d6565b505050565b6001546001600160a01b0316331461142e5760405162461bcd60e51b815260040161057a90612b7f565b600181600281111561144257611442612855565b0361145057611450826121a3565b600281600281111561146457611464612855565b036106185761061882612315565b6000806006848154811061148857611488612bcc565b600091825260208083208784526007825260408085206001600160a01b0389168652909252908320600892909202016004810154600682015491945091929060ff1661153e5783546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611515573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115399190612bff565b6115b0565b60068401546040516370a0823160e01b81523060048201526101009091046001600160a01b0316906370a0823190602401602060405180830381865afa15801561158c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b09190612bff565b90508360030154421180156115c457508015155b156116215760006115d98560030154426108bf565b905060006115fa600854610d89886002015485611d3390919063ffffffff16565b905061161c61161584610d8984670de0b6b3a7640000611d33565b8590611d3f565b935050505b61164c8360010154610d8f670de0b6b3a7640000610d89868860000154611d3390919063ffffffff16565b979650505050505050565b61165f611d4b565b600033905060006006848154811061167957611679612bcc565b600091825260208083208784526007825260408085206001600160a01b03881686529092529220600890910290910191506116b385611da4565b8054156117435760006116eb8260010154610d8f670de0b6b3a7640000610d8987600401548760000154611d3390919063ffffffff16565b90508015611741576116fd8482611fbf565b836001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e04868260405161173891815260200190565b60405180910390a25b505b83156117b6578154611760906001600160a01b03168430876123f0565b600061177f612710610d89856001015488611d3390919063ffffffff16565b905061179661178e8683611d20565b835490611d3f565b825560055483546117b4916001600160a01b03918216911683611cbd565b505b6117bf85610984565b600482015481546117dd91670de0b6b3a764000091610d8991611d33565b600182015560405184815285906001600160a01b038516907f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a159060200160405180910390a35050506106186001600055565b6001546001600160a01b031633146118595760405162461bcd60e51b815260040161057a90612b7f565b60028054911515600160a81b0260ff60a81b19909216919091179055565b6001546001600160a01b031633146118a15760405162461bcd60e51b815260040161057a90612b7f565b84831480156118af57508481145b6119055760405162461bcd60e51b815260206004820152602160248201527f474d6174726978526577617264506f6f6c3a20696e76616c6964206c656e67746044820152600d60fb1b606482015260840161057a565b60005b8581101561196b5761196387878381811061192557611925612bcc565b9050602002013586868481811061193e5761193e612bcc565b9050602002013585858581811061195757611957612bcc565b90506020020135610be2565b600101611908565b50505050505050565b60006006828154811061198957611989612bcc565b9060005260206000209060080201905060008160060160000160019054906101000a90046001600160a01b03166001600160a01b0316638003b6146040518163ffffffff1660e01b8152600401600060405180830381865afa1580156119f3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611a1b9190810190612c6d565b60068301546040516331279d3d60e01b815291925061010090046001600160a01b0316906331279d3d90611a559030908590600401612d3d565b600060405180830381600087803b158015611a6f57600080fd5b505af1158015611a83573d6000803e3d6000fd5b5050505060005b8151811015610b93576000828281518110611aa757611aa7612bcc565b60209081029190910101516040516370a0823160e01b81523060048201529091506000906001600160a01b038316906370a0823190602401602060405180830381865afa158015611afc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b209190612bff565b90508015611b8b57735050bc082ff4a74fb6b0b04385defddb114b2423196001600160a01b03831601611b7157600254600160a81b900460ff161515600103611b6c57611b6c81612428565b611b8b565b600554611b8b906001600160a01b03848116911683611cbd565b5050600101611a8a565b600060068281548110611baa57611baa612bcc565b906000526020600020906008020190508060060160000160019054906101000a90046001600160a01b03166001600160a01b0316633d18b9126040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611c0f57600080fd5b505af1158015611c23573d6000803e3d6000fd5b50506040516370a0823160e01b815230600482015273a04bc7140c26fc9bb1f36b1a604c7a5a88fb0e7092506000915082906370a0823190602401602060405180830381865afa158015611c7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c9f9190612bff565b90508015610b9357600554610b93906001600160a01b038481169116835b6040516001600160a01b0383166024820152604481018290526113ff90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526125e7565b6000611d2c8284612d9c565b9392505050565b6000611d2c8284612daf565b6000611d2c8284612dc6565b600260005403611d9d5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161057a565b6002600055565b611dad81610984565b600060068281548110611dc257611dc2612bcc565b9060005260206000209060080201905080600301544211611de1575050565b600681015460009060ff16611e605781546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611e37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e5b9190612bff565b611ed2565b60068201546040516370a0823160e01b81523060048201526101009091046001600160a01b0316906370a0823190602401602060405180830381865afa158015611eae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ed29190612bff565b905080600003611ee757504260039091015550565b600582015460ff16611f2b5760058201805460ff191660011790556002820154600854611f1391611d3f565b6008556007820154600b54611f2791611d3f565b600b555b60085415611f92576000611f438360030154426108bf565b90506000611f64600854610d89866002015485611d3390919063ffffffff16565b9050611f8a611f7f84610d8984670de0b6b3a7640000611d33565b600486015490611d3f565b600485015550505b426003830155600254600160a01b900460ff16156113ff576113ff83610550565b6000611d2c8284612dd9565b6002546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612008573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202c9190612bff565b905080156113ff5780821115612053576002546113ff906001600160a01b03168483611cbd565b6002546113ff906001600160a01b03168484611cbd565b60006006838154811061207f5761207f612bcc565b60009182526020909120600890910201600681015490915060ff16156113ff576006810154604051632e1a7d4d60e01b8152600481018490526101009091046001600160a01b031690632e1a7d4d90602401600060405180830381600087803b1580156120eb57600080fd5b505af115801561196b573d6000803e3d6000fd5b60065460005b818110156113ff57826001600160a01b03166006828154811061212a5761212a612bcc565b60009182526020909120600890910201546001600160a01b03160361219b5760405162461bcd60e51b815260206004820152602160248201527f474d6174726978526577617264506f6f6c3a206578697374696e6720706f6f6c6044820152603f60f81b606482015260840161057a565b600101612105565b600354600680546000926001600160a01b031691632045be9091859081106121cd576121cd612bcc565b600091825260209091206008909102015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015612222573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122469190612dfb565b90506001600160a01b03811615610618576040805160608101825260018082526001600160a01b038416602083015290918201905b8152506006838154811061229157612291612bcc565b6000918252602091829020835160066008909302909101919091018054928401516001600160a01b031661010002610100600160a81b0319921515929092166001600160a81b03199093169290921717808255604083015190829060ff60a81b1916600160a81b83600281111561230a5761230a612855565b021790555050505050565b600454600680546000926001600160a01b03169163b9a09fd5918590811061233f5761233f612bcc565b600091825260209091206008909102015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015612394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123b89190612dfb565b90506001600160a01b038116156106185760408051606081018252600181526001600160a01b0383166020820152908101600261227b565b6040516001600160a01b0380851660248301528316604482015260648101829052610b939085906323b872dd60e01b90608401611ce9565b60405163095ea7b360e01b8152733333111a391cc08fa51353e9195526a70b333333600482015260248101829052735050bc082ff4a74fb6b0b04385defddb114b24249063095ea7b3906044016020604051808303816000875af1158015612494573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124b89190612be2565b506000733333111a391cc08fa51353e9195526a70b3333336001600160a01b0316638380edb76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561250d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125319190612be2565b9050801561061857604051636e553f6560e01b815260048101839052306024820152600090733333111a391cc08fa51353e9195526a70b33333390636e553f65906044016020604051808303816000875af1158015612594573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125b89190612bff565b6005549091506113ff90733333111a391cc08fa51353e9195526a70b333333906001600160a01b031683611cbd565b600061263c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166126bc9092919063ffffffff16565b905080516000148061265d57508080602001905181019061265d9190612be2565b6113ff5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161057a565b60606126cb84846000856126d3565b949350505050565b6060824710156127345760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161057a565b600080866001600160a01b031685876040516127509190612e3c565b60006040518083038185875af1925050503d806000811461278d576040519150601f19603f3d011682016040523d82523d6000602084013e612792565b606091505b509150915061164c878383876060831561280d578251600003612806576001600160a01b0385163b6128065760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161057a565b50816126cb565b6126cb83838151156128225781518083602001fd5b8060405162461bcd60e51b815260040161057a9190612e58565b60006020828403121561284e57600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b6001600160a01b03898116825260208083018a905260408084018a9052606084018990526080840188905286151560a08501528551151560c08501529085015190911660e0830152830151610140820190600381106128da57634e487b7160e01b600052602160045260246000fd5b61010083015261012090910191909152979650505050505050565b6000806040838503121561290857600080fd5b50508035926020909101359150565b60008060006060848603121561292c57600080fd5b505081359360208301359350604090920135919050565b6001600160a01b0381168114610f4557600080fd5b60008060006060848603121561296d57600080fd5b833561297881612943565b925060208401359150604084013561298f81612943565b809150509250925092565b8015158114610f4557600080fd5b6000602082840312156129ba57600080fd5b8135611d2c8161299a565b600080600080600060a086880312156129dd57600080fd5b853594506020860135935060408601356129f681612943565b92506060860135612a068161299a565b949793965091946080013592915050565b60008060408385031215612a2a57600080fd5b823591506020830135612a3c81612943565b809150509250929050565b600060208284031215612a5957600080fd5b8135611d2c81612943565b60008060408385031215612a7757600080fd5b82359150602083013560038110612a3c57600080fd5b60008083601f840112612a9f57600080fd5b50813567ffffffffffffffff811115612ab757600080fd5b6020830191508360208260051b8501011115612ad257600080fd5b9250929050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff811115612b0957600080fd5b612b1589828a01612a8d565b909750955050602087013567ffffffffffffffff811115612b3557600080fd5b612b4189828a01612a8d565b909550935050604087013567ffffffffffffffff811115612b6157600080fd5b612b6d89828a01612a8d565b979a9699509497509295939492505050565b6020808252602d908201527f474d6174726978526577617264506f6f6c3a2063616c6c6572206973206e6f7460408201526c103a34329037b832b930ba37b960991b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b600060208284031215612bf457600080fd5b8151611d2c8161299a565b600060208284031215612c1157600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600060018201612c4057612c40612c18565b5060010190565b634e487b7160e01b600052604160045260246000fd5b8051612c6881612943565b919050565b600060208284031215612c7f57600080fd5b815167ffffffffffffffff811115612c9657600080fd5b8201601f81018413612ca757600080fd5b805167ffffffffffffffff811115612cc157612cc1612c47565b8060051b604051601f19603f830116810181811067ffffffffffffffff82111715612cee57612cee612c47565b604052918252602081840181019290810187841115612d0c57600080fd5b6020850194505b83851015612d3257612d2485612c5d565b815260209485019401612d13565b509695505050505050565b6001600160a01b0383168152604060208083018290528351918301829052600091908401906060840190835b81811015612d905783516001600160a01b0316835260209384019390920191600101612d69565b50909695505050505050565b8181038181111561097e5761097e612c18565b808202811582820484141761097e5761097e612c18565b8082018082111561097e5761097e612c18565b600082612df657634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215612e0d57600080fd5b8151611d2c81612943565b60005b83811015612e33578181015183820152602001612e1b565b50506000910152565b60008251612e4e818460208701612e18565b9190910192915050565b6020815260008251806020840152612e77816040850160208701612e18565b601f01601f1916919091016040019291505056fea2646970667358221220436e7047253a2e03c55138323b340a9fbefd58c457b0fb7e18f926c781c4ad5364736f6c634300081a0033474d6174726978526577617264506f6f6c3a2063616c6c6572206973206e6f740000000000000000000000006ccb729491e66eb96db1b477af5c687387fa668100000000000000000000000000e2aafd3de98517ec86d91b25a1161cc3b5ca3d0000000000000000000000000000000000000000000000000000000067d31d200000000000000000000000009f59398d0a397b2eeb8a6123a6c7295cb0b0062d000000000000000000000000c1ae2779903cfb84cb9dee5c03eceac32dc407f2
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102315760003560e01c8063570ca73511610130578063943f013d116100b8578063cf4b55cb1161007c578063cf4b55cb146104e9578063dfbffa8c146104fc578063e2bbb15814610517578063f11287341461052a578063fddc298c1461053d57600080fd5b8063943f013d14610494578063ae4db9191461049d578063b3ab15fb146104b0578063b947a88d146104c3578063ce862f17146104d657600080fd5b806363eb0416116100ff57806363eb04161461040b5780636e142c8e1461041e5780636e271dd51461043157806390c5ed6a1461043a57806393f1a40b1461044d57600080fd5b8063570ca735146103de5780635752933a146103f15780635f96dc11146103fa578063630b5ba11461040357600080fd5b80633202f6c1116101be57806343b0e8df1161018257806343b0e8df14610377578063441a3e701461038a5780635312ea8e1461039d57806354575af4146103b0578063549c278a146103c357600080fd5b80633202f6c1146103115780633aa158ee146103245780633afb24f11461032c5780634189fafa146103505780634390d2a81461036457600080fd5b80631526fe27116102055780631526fe27146102a857806317caf6f1146102cf5780631f7cceec146102d8578063231f0c6a146102eb5780632df95ed7146102fe57600080fd5b8062c6b39114610236578063081e3eda1461026e57806308428f6d146102805780630998bb4014610293575b600080fd5b610251735050bc082ff4a74fb6b0b04385defddb114b242481565b6040516001600160a01b0390911681526020015b60405180910390f35b6006545b604051908152602001610265565b600254610251906001600160a01b031681565b6102a66102a136600461283c565b610550565b005b6102bb6102b636600461283c565b61061c565b60405161026598979695949392919061286b565b61027260085481565b6102a66102e636600461283c565b6106db565b6102726102f93660046128f5565b6108bf565b6102a661030c36600461283c565b610984565b600354610251906001600160a01b031681565b6102a6610b99565b60025461034090600160a01b900460ff1681565b6040519015158152602001610265565b60025461034090600160a81b900460ff1681565b600554610251906001600160a01b031681565b6102a6610385366004612917565b610be2565b6102a66103983660046128f5565b610cad565b6102a66103ab36600461283c565b610e90565b6102a66103be366004612958565b610f48565b610251733333111a391cc08fa51353e9195526a70b33333381565b600154610251906001600160a01b031681565b610272600b5481565b61027260095481565b6102a6611037565b6102a66104193660046129a8565b61105f565b600454610251906001600160a01b031681565b610272600a5481565b6102a66104483660046129c5565b6110a7565b61047f61045b366004612a17565b60076020908152600092835260408084209091529082529020805460019091015482565b60408051928352602083019190915201610265565b610272600c5481565b6102a66104ab366004612a47565b6112ec565b6102a66104be366004612a47565b611338565b6102a66104d13660046128f5565b611384565b6102a66104e4366004612a64565b611404565b6102726104f7366004612a17565b611472565b61025173a04bc7140c26fc9bb1f36b1a604c7a5a88fb0e7081565b6102a66105253660046128f5565b611657565b6102a66105383660046129a8565b61182f565b6102a661054b366004612ad9565b611877565b6001546001600160a01b031633146105835760405162461bcd60e51b815260040161057a90612b7f565b60405180910390fd5b60006006828154811061059857610598612bcc565b60009182526020909120600890910201600681015490915060ff16156106185760016006820154600160a81b900460ff1660028111156105da576105da612855565b036105e8576105e882611974565b60026006820154600160a81b900460ff16600281111561060a5761060a612855565b036106185761061882611b95565b5050565b6006818154811061062c57600080fd5b6000918252602091829020600890910201805460018201546002808401546003850154600486015460058701546040805160608101825260068a01805460ff8181161515845261010082046001600160a01b039081169e85019e909e529c909a169c50979a9599949893979286169694959094929391850192600160a81b90920416908111156106be576106be612855565b60028111156106cf576106cf612855565b90525060079091015488565b6001546001600160a01b031633146107055760405162461bcd60e51b815260040161057a90612b7f565b60405163095ea7b360e01b8152733333111a391cc08fa51353e9195526a70b333333600482015260248101829052735050bc082ff4a74fb6b0b04385defddb114b24249063095ea7b3906044016020604051808303816000875af1158015610771573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107959190612be2565b506000733333111a391cc08fa51353e9195526a70b3333336001600160a01b0316638380edb76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080e9190612be2565b9050801561061857604051636e553f6560e01b815260048101839052306024820152733333111a391cc08fa51353e9195526a70b33333390636e553f65906044016020604051808303816000875af115801561086e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108929190612bff565b5060055461061890733333111a391cc08fa51353e9195526a70b333333906001600160a01b031684611cbd565b60008183106108d05750600061097e565b600a54821061093857600a5483106108ea5750600061097e565b600954831161091d57610916600b54610910600954600a54611d2090919063ffffffff16565b90611d33565b905061097e565b610916600b5461091085600a54611d2090919063ffffffff16565b60095482116109495750600061097e565b600954831161096d57610916600b5461091060095485611d2090919063ffffffff16565b600b54610916906109108486611d20565b92915050565b60006006828154811061099957610999612bcc565b60009182526020822060089190910201600681015481546040516370a0823160e01b81523060048201529294506101009091046001600160a01b0390811693929116906370a0823190602401602060405180830381865afa158015610a02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a269190612bff565b600684015490915060ff1615610b93578015610b93578254604051636eb1769f60e11b81523060048201526001600160a01b0384811660248301528392169063dd62ed3e90604401602060405180830381865afa158015610a8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aaf9190612bff565b1015610b2e57825460405163095ea7b360e01b81526001600160a01b03848116600483015260001960248301529091169063095ea7b3906044016020604051808303816000875af1158015610b08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2c9190612be2565b505b600683015460405163b6b55f2560e01b8152600481018390526101009091046001600160a01b03169063b6b55f2590602401600060405180830381600087803b158015610b7a57600080fd5b505af1158015610b8e573d6000803e3d6000fd5b505050505b50505050565b6001546001600160a01b03163314610bc35760405162461bcd60e51b815260040161057a90612b7f565b60065460005b8181101561061857610bda81610550565b600101610bc9565b6001546001600160a01b03163314610c0c5760405162461bcd60e51b815260040161057a90612b7f565b610c14611037565b600060068481548110610c2957610c29612bcc565b9060005260206000209060080201905060c88210610c4657600080fd5b60018101829055600581015460ff1615610c9b57610c7d83610c778360020154600854611d2090919063ffffffff16565b90611d3f565b6008556007810154600b54610c97918591610c7791611d20565b600b555b60028101839055600701919091555050565b610cb5611d4b565b6000339050600060068481548110610ccf57610ccf612bcc565b600091825260208083208784526007825260408085206001600160a01b03881686529092529220805460089092029092019250841115610d465760405162461bcd60e51b81526020600482015260126024820152711dda5d1a191c985dce881b9bdd0819dbdbd960721b604482015260640161057a565b610d4f85611da4565b610d5885610984565b6000610d958260010154610d8f670de0b6b3a7640000610d8987600401548760000154611d3390919063ffffffff16565b90611fb3565b90611d20565b90508015610deb57610da78482611fbf565b836001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e048682604051610de291815260200190565b60405180910390a25b8415610e1f578154610dfd9086611d20565b8255610e09868661206a565b8254610e1f906001600160a01b03168587611cbd565b60048301548254610e3d91670de0b6b3a764000091610d8991611d33565b600183015560405185815286906001600160a01b038616907ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5689060200160405180910390a3505050506106186001600055565b610e98611d4b565b600060068281548110610ead57610ead612bcc565b600091825260208083208584526007825260408085203386529092529220805460089092029092019250610ee1848261206a565b600080835560018301558254610f01906001600160a01b03163383611cbd565b604051818152849033907fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05959060200160405180910390a3505050610f456001600055565b50565b6001546001600160a01b03163314610f725760405162461bcd60e51b815260040161057a90612b7f565b60065460005b8181101561102257600060068281548110610f9557610f95612bcc565b6000918252602090912060089091020180549091506001600160a01b03908116908716036110195760405162461bcd60e51b815260206004820152602b60248201527f5368617265526577617264506f6f6c3a20546f6b656e2063616e6e6f7420626560448201526a103837b7b6103a37b5b2b760a91b606482015260840161057a565b50600101610f78565b50610b936001600160a01b0385168385611cbd565b60065460005b818110156106185761104e81611da4565b61105781610984565b60010161103d565b6001546001600160a01b031633146110895760405162461bcd60e51b815260040161057a90612b7f565b60028054911515600160a01b0260ff60a01b19909216919091179055565b6001546001600160a01b031633146110d15760405162461bcd60e51b815260040161057a90612b7f565b6110da836120ff565b81156110e8576110e8611037565b6009544210156111175780600003611103575060095461112b565b60095481101561111257506009545b61112b565b80158061112357504281105b1561112b5750425b60006009548211158061113e5750428211155b90506006604051806101000160405280866001600160a01b03168152602001878152602001888152602001848152602001600081526020018315158152602001604051806060016040528060001515815260200160006001600160a01b03168152602001600060028111156111b5576111b5612855565b905281526020908101899052825460018181018555600094855293829020835160089092020180546001600160a01b039283166001600160a01b03199091161781558383015194810194909455604080840151600280870191909155606085015160038701556080850151600487015560a085015160058701805491151560ff1990921691909117905560c085015180516006880180549683015190951661010002610100600160a81b0319911515919091166001600160a81b031990961695909517949094178084559184015194959491839160ff60a81b1990911690600160a81b9084908111156112aa576112aa612855565b0217905550505060e08201518160070155505080156112e4576008546112d09087611d3f565b600855600b546112e09087611d3f565b600b555b505050505050565b6001546001600160a01b031633146113165760405162461bcd60e51b815260040161057a90612b7f565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633146113625760405162461bcd60e51b815260040161057a90612b7f565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b808211156113d45760405162461bcd60e51b815260206004820181905260248201527f474d6174726978526577617264506f6f6c3a20696e76616c69642072616e6765604482015260640161057a565b815b8181116113ff576113e681611da4565b6113ef81610984565b6113f881612c2e565b90506113d6565b505050565b6001546001600160a01b0316331461142e5760405162461bcd60e51b815260040161057a90612b7f565b600181600281111561144257611442612855565b0361145057611450826121a3565b600281600281111561146457611464612855565b036106185761061882612315565b6000806006848154811061148857611488612bcc565b600091825260208083208784526007825260408085206001600160a01b0389168652909252908320600892909202016004810154600682015491945091929060ff1661153e5783546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611515573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115399190612bff565b6115b0565b60068401546040516370a0823160e01b81523060048201526101009091046001600160a01b0316906370a0823190602401602060405180830381865afa15801561158c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b09190612bff565b90508360030154421180156115c457508015155b156116215760006115d98560030154426108bf565b905060006115fa600854610d89886002015485611d3390919063ffffffff16565b905061161c61161584610d8984670de0b6b3a7640000611d33565b8590611d3f565b935050505b61164c8360010154610d8f670de0b6b3a7640000610d89868860000154611d3390919063ffffffff16565b979650505050505050565b61165f611d4b565b600033905060006006848154811061167957611679612bcc565b600091825260208083208784526007825260408085206001600160a01b03881686529092529220600890910290910191506116b385611da4565b8054156117435760006116eb8260010154610d8f670de0b6b3a7640000610d8987600401548760000154611d3390919063ffffffff16565b90508015611741576116fd8482611fbf565b836001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e04868260405161173891815260200190565b60405180910390a25b505b83156117b6578154611760906001600160a01b03168430876123f0565b600061177f612710610d89856001015488611d3390919063ffffffff16565b905061179661178e8683611d20565b835490611d3f565b825560055483546117b4916001600160a01b03918216911683611cbd565b505b6117bf85610984565b600482015481546117dd91670de0b6b3a764000091610d8991611d33565b600182015560405184815285906001600160a01b038516907f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a159060200160405180910390a35050506106186001600055565b6001546001600160a01b031633146118595760405162461bcd60e51b815260040161057a90612b7f565b60028054911515600160a81b0260ff60a81b19909216919091179055565b6001546001600160a01b031633146118a15760405162461bcd60e51b815260040161057a90612b7f565b84831480156118af57508481145b6119055760405162461bcd60e51b815260206004820152602160248201527f474d6174726978526577617264506f6f6c3a20696e76616c6964206c656e67746044820152600d60fb1b606482015260840161057a565b60005b8581101561196b5761196387878381811061192557611925612bcc565b9050602002013586868481811061193e5761193e612bcc565b9050602002013585858581811061195757611957612bcc565b90506020020135610be2565b600101611908565b50505050505050565b60006006828154811061198957611989612bcc565b9060005260206000209060080201905060008160060160000160019054906101000a90046001600160a01b03166001600160a01b0316638003b6146040518163ffffffff1660e01b8152600401600060405180830381865afa1580156119f3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611a1b9190810190612c6d565b60068301546040516331279d3d60e01b815291925061010090046001600160a01b0316906331279d3d90611a559030908590600401612d3d565b600060405180830381600087803b158015611a6f57600080fd5b505af1158015611a83573d6000803e3d6000fd5b5050505060005b8151811015610b93576000828281518110611aa757611aa7612bcc565b60209081029190910101516040516370a0823160e01b81523060048201529091506000906001600160a01b038316906370a0823190602401602060405180830381865afa158015611afc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b209190612bff565b90508015611b8b57735050bc082ff4a74fb6b0b04385defddb114b2423196001600160a01b03831601611b7157600254600160a81b900460ff161515600103611b6c57611b6c81612428565b611b8b565b600554611b8b906001600160a01b03848116911683611cbd565b5050600101611a8a565b600060068281548110611baa57611baa612bcc565b906000526020600020906008020190508060060160000160019054906101000a90046001600160a01b03166001600160a01b0316633d18b9126040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611c0f57600080fd5b505af1158015611c23573d6000803e3d6000fd5b50506040516370a0823160e01b815230600482015273a04bc7140c26fc9bb1f36b1a604c7a5a88fb0e7092506000915082906370a0823190602401602060405180830381865afa158015611c7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c9f9190612bff565b90508015610b9357600554610b93906001600160a01b038481169116835b6040516001600160a01b0383166024820152604481018290526113ff90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526125e7565b6000611d2c8284612d9c565b9392505050565b6000611d2c8284612daf565b6000611d2c8284612dc6565b600260005403611d9d5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161057a565b6002600055565b611dad81610984565b600060068281548110611dc257611dc2612bcc565b9060005260206000209060080201905080600301544211611de1575050565b600681015460009060ff16611e605781546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611e37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e5b9190612bff565b611ed2565b60068201546040516370a0823160e01b81523060048201526101009091046001600160a01b0316906370a0823190602401602060405180830381865afa158015611eae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ed29190612bff565b905080600003611ee757504260039091015550565b600582015460ff16611f2b5760058201805460ff191660011790556002820154600854611f1391611d3f565b6008556007820154600b54611f2791611d3f565b600b555b60085415611f92576000611f438360030154426108bf565b90506000611f64600854610d89866002015485611d3390919063ffffffff16565b9050611f8a611f7f84610d8984670de0b6b3a7640000611d33565b600486015490611d3f565b600485015550505b426003830155600254600160a01b900460ff16156113ff576113ff83610550565b6000611d2c8284612dd9565b6002546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612008573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202c9190612bff565b905080156113ff5780821115612053576002546113ff906001600160a01b03168483611cbd565b6002546113ff906001600160a01b03168484611cbd565b60006006838154811061207f5761207f612bcc565b60009182526020909120600890910201600681015490915060ff16156113ff576006810154604051632e1a7d4d60e01b8152600481018490526101009091046001600160a01b031690632e1a7d4d90602401600060405180830381600087803b1580156120eb57600080fd5b505af115801561196b573d6000803e3d6000fd5b60065460005b818110156113ff57826001600160a01b03166006828154811061212a5761212a612bcc565b60009182526020909120600890910201546001600160a01b03160361219b5760405162461bcd60e51b815260206004820152602160248201527f474d6174726978526577617264506f6f6c3a206578697374696e6720706f6f6c6044820152603f60f81b606482015260840161057a565b600101612105565b600354600680546000926001600160a01b031691632045be9091859081106121cd576121cd612bcc565b600091825260209091206008909102015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015612222573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122469190612dfb565b90506001600160a01b03811615610618576040805160608101825260018082526001600160a01b038416602083015290918201905b8152506006838154811061229157612291612bcc565b6000918252602091829020835160066008909302909101919091018054928401516001600160a01b031661010002610100600160a81b0319921515929092166001600160a81b03199093169290921717808255604083015190829060ff60a81b1916600160a81b83600281111561230a5761230a612855565b021790555050505050565b600454600680546000926001600160a01b03169163b9a09fd5918590811061233f5761233f612bcc565b600091825260209091206008909102015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015612394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123b89190612dfb565b90506001600160a01b038116156106185760408051606081018252600181526001600160a01b0383166020820152908101600261227b565b6040516001600160a01b0380851660248301528316604482015260648101829052610b939085906323b872dd60e01b90608401611ce9565b60405163095ea7b360e01b8152733333111a391cc08fa51353e9195526a70b333333600482015260248101829052735050bc082ff4a74fb6b0b04385defddb114b24249063095ea7b3906044016020604051808303816000875af1158015612494573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124b89190612be2565b506000733333111a391cc08fa51353e9195526a70b3333336001600160a01b0316638380edb76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561250d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125319190612be2565b9050801561061857604051636e553f6560e01b815260048101839052306024820152600090733333111a391cc08fa51353e9195526a70b33333390636e553f65906044016020604051808303816000875af1158015612594573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125b89190612bff565b6005549091506113ff90733333111a391cc08fa51353e9195526a70b333333906001600160a01b031683611cbd565b600061263c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166126bc9092919063ffffffff16565b905080516000148061265d57508080602001905181019061265d9190612be2565b6113ff5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161057a565b60606126cb84846000856126d3565b949350505050565b6060824710156127345760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161057a565b600080866001600160a01b031685876040516127509190612e3c565b60006040518083038185875af1925050503d806000811461278d576040519150601f19603f3d011682016040523d82523d6000602084013e612792565b606091505b509150915061164c878383876060831561280d578251600003612806576001600160a01b0385163b6128065760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161057a565b50816126cb565b6126cb83838151156128225781518083602001fd5b8060405162461bcd60e51b815260040161057a9190612e58565b60006020828403121561284e57600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b6001600160a01b03898116825260208083018a905260408084018a9052606084018990526080840188905286151560a08501528551151560c08501529085015190911660e0830152830151610140820190600381106128da57634e487b7160e01b600052602160045260246000fd5b61010083015261012090910191909152979650505050505050565b6000806040838503121561290857600080fd5b50508035926020909101359150565b60008060006060848603121561292c57600080fd5b505081359360208301359350604090920135919050565b6001600160a01b0381168114610f4557600080fd5b60008060006060848603121561296d57600080fd5b833561297881612943565b925060208401359150604084013561298f81612943565b809150509250925092565b8015158114610f4557600080fd5b6000602082840312156129ba57600080fd5b8135611d2c8161299a565b600080600080600060a086880312156129dd57600080fd5b853594506020860135935060408601356129f681612943565b92506060860135612a068161299a565b949793965091946080013592915050565b60008060408385031215612a2a57600080fd5b823591506020830135612a3c81612943565b809150509250929050565b600060208284031215612a5957600080fd5b8135611d2c81612943565b60008060408385031215612a7757600080fd5b82359150602083013560038110612a3c57600080fd5b60008083601f840112612a9f57600080fd5b50813567ffffffffffffffff811115612ab757600080fd5b6020830191508360208260051b8501011115612ad257600080fd5b9250929050565b60008060008060008060608789031215612af257600080fd5b863567ffffffffffffffff811115612b0957600080fd5b612b1589828a01612a8d565b909750955050602087013567ffffffffffffffff811115612b3557600080fd5b612b4189828a01612a8d565b909550935050604087013567ffffffffffffffff811115612b6157600080fd5b612b6d89828a01612a8d565b979a9699509497509295939492505050565b6020808252602d908201527f474d6174726978526577617264506f6f6c3a2063616c6c6572206973206e6f7460408201526c103a34329037b832b930ba37b960991b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b600060208284031215612bf457600080fd5b8151611d2c8161299a565b600060208284031215612c1157600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600060018201612c4057612c40612c18565b5060010190565b634e487b7160e01b600052604160045260246000fd5b8051612c6881612943565b919050565b600060208284031215612c7f57600080fd5b815167ffffffffffffffff811115612c9657600080fd5b8201601f81018413612ca757600080fd5b805167ffffffffffffffff811115612cc157612cc1612c47565b8060051b604051601f19603f830116810181811067ffffffffffffffff82111715612cee57612cee612c47565b604052918252602081840181019290810187841115612d0c57600080fd5b6020850194505b83851015612d3257612d2485612c5d565b815260209485019401612d13565b509695505050505050565b6001600160a01b0383168152604060208083018290528351918301829052600091908401906060840190835b81811015612d905783516001600160a01b0316835260209384019390920191600101612d69565b50909695505050505050565b8181038181111561097e5761097e612c18565b808202811582820484141761097e5761097e612c18565b8082018082111561097e5761097e612c18565b600082612df657634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215612e0d57600080fd5b8151611d2c81612943565b60005b83811015612e33578181015183820152602001612e1b565b50506000910152565b60008251612e4e818460208701612e18565b9190910192915050565b6020815260008251806020840152612e77816040850160208701612e18565b601f01601f1916919091016040019291505056fea2646970667358221220436e7047253a2e03c55138323b340a9fbefd58c457b0fb7e18f926c781c4ad5364736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006ccb729491e66eb96db1b477af5c687387fa668100000000000000000000000000e2aafd3de98517ec86d91b25a1161cc3b5ca3d0000000000000000000000000000000000000000000000000000000067d31d200000000000000000000000009f59398d0a397b2eeb8a6123a6c7295cb0b0062d000000000000000000000000c1ae2779903cfb84cb9dee5c03eceac32dc407f2
-----Decoded View---------------
Arg [0] : _gmatrix (address): 0x6CCb729491e66eB96db1b477aF5c687387FA6681
Arg [1] : _devFund (address): 0x00E2AAFd3dE98517EC86d91b25A1161cC3b5cA3D
Arg [2] : _poolStartTime (uint256): 1741888800
Arg [3] : _shadowVoter (address): 0x9F59398D0a397b2EEB8a6123a6c7295cB0b0062D
Arg [4] : _swapxVoter (address): 0xC1AE2779903cfB84CB9DEe5c03EcEAc32dc407F2
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000006ccb729491e66eb96db1b477af5c687387fa6681
Arg [1] : 00000000000000000000000000e2aafd3de98517ec86d91b25a1161cc3b5ca3d
Arg [2] : 0000000000000000000000000000000000000000000000000000000067d31d20
Arg [3] : 0000000000000000000000009f59398d0a397b2eeb8a6123a6c7295cb0b0062d
Arg [4] : 000000000000000000000000c1ae2779903cfb84cb9dee5c03eceac32dc407f2
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.