More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 38 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Withdraw | 21550324 | 12 days ago | IN | 0 ETH | 0.00185331 | ||||
Withdraw | 21428462 | 29 days ago | IN | 0 ETH | 0.00303737 | ||||
Withdraw | 21214609 | 58 days ago | IN | 0 ETH | 0.00271022 | ||||
Withdraw | 21128670 | 70 days ago | IN | 0 ETH | 0.00553505 | ||||
Withdraw | 20758156 | 122 days ago | IN | 0 ETH | 0.00070992 | ||||
Deposit | 20469565 | 162 days ago | IN | 0 ETH | 0.00091564 | ||||
Withdraw | 20393920 | 173 days ago | IN | 0 ETH | 0.00047422 | ||||
Withdraw | 20070339 | 218 days ago | IN | 0 ETH | 0.00324469 | ||||
Withdraw | 19706388 | 269 days ago | IN | 0 ETH | 0.00196656 | ||||
Withdraw | 19606004 | 283 days ago | IN | 0 ETH | 0.00410774 | ||||
Withdraw | 19300743 | 326 days ago | IN | 0 ETH | 0.0051481 | ||||
Withdraw | 19247979 | 333 days ago | IN | 0 ETH | 0.0054208 | ||||
Withdraw | 19211359 | 338 days ago | IN | 0 ETH | 0.00523378 | ||||
Withdraw | 19167120 | 345 days ago | IN | 0 ETH | 0.00429544 | ||||
Withdraw | 19000742 | 368 days ago | IN | 0 ETH | 0.00396194 | ||||
Withdraw | 18970515 | 372 days ago | IN | 0 ETH | 0.00592031 | ||||
Withdraw | 18909136 | 381 days ago | IN | 0 ETH | 0.00299902 | ||||
Withdraw | 18906958 | 381 days ago | IN | 0 ETH | 0.00447592 | ||||
Withdraw | 18769416 | 400 days ago | IN | 0 ETH | 0.01479124 | ||||
Withdraw | 18605555 | 423 days ago | IN | 0 ETH | 0.01051812 | ||||
Withdraw | 18377208 | 455 days ago | IN | 0 ETH | 0.0102897 | ||||
Withdraw | 18344436 | 460 days ago | IN | 0 ETH | 0.00475298 | ||||
Withdraw | 18208723 | 479 days ago | IN | 0 ETH | 0.00420643 | ||||
Approve | 18208565 | 479 days ago | IN | 0 ETH | 0.00037132 | ||||
Deposit | 18208561 | 479 days ago | IN | 0 ETH | 0.00539158 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
DullahanVault
Compiler Version
v0.8.16+commit.07a7930e
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
//██████╗ █████╗ ██╗ █████╗ ██████╗ ██╗███╗ ██╗ //██╔══██╗██╔══██╗██║ ██╔══██╗██╔══██╗██║████╗ ██║ //██████╔╝███████║██║ ███████║██║ ██║██║██╔██╗ ██║ //██╔═══╝ ██╔══██║██║ ██╔══██║██║ ██║██║██║╚██╗██║ //██║ ██║ ██║███████╗██║ ██║██████╔╝██║██║ ╚████║ //╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═════╝ ╚═╝╚═╝ ╚═══╝ pragma solidity 0.8.16; //SPDX-License-Identifier: BUSL-1.1 import "./base/ScalingERC20.sol"; import "./interfaces/IERC4626.sol"; import "./oz/interfaces/IERC20.sol"; import "./oz/libraries/SafeERC20.sol"; import "./oz/utils/ReentrancyGuard.sol"; import "./oz/utils/Pausable.sol"; import "./interfaces/IStakedAave.sol"; import "./interfaces/IGovernancePowerDelegationToken.sol"; import {Errors} from "./utils/Errors.sol"; import {WadRayMath} from "./utils/WadRayMath.sol"; /** @title DullahanVault contract * @author Paladin * @notice Main Dullahan Vault. IERC4626 compatible & ScalingERC20 token */ contract DullahanVault is IERC4626, ScalingERC20, ReentrancyGuard, Pausable { using SafeERC20 for IERC20; using WadRayMath for uint256; // Constants /** @notice Max value for BPS - 100% */ uint256 public constant MAX_BPS = 10000; /** @notice Max value possible for an uint256 */ uint256 public constant MAX_UINT256 = 2**256 - 1; /** @notice Amount to deposit to seed the Vault during initialization */ uint256 private constant SEED_DEPOSIT = 0.001 ether; /** @notice Address of the stkAAVE token */ address public immutable STK_AAVE; /** @notice Address of the AAVE token */ address public immutable AAVE; // Struct /** @notice PodsManager struct * rentingAllowed: Is the Manager allowed to rent from the Vault * totalRented: Total amount rented to the Manager (based on the AAVE max total supply, should be safe) */ struct PodsManager { bool rentingAllowed; uint248 totalRented; } // Storage /** @notice Is the Vault initialized */ bool public initialized; /** @notice Address of the Vault admin */ address public admin; /** @notice Address of the Vault pending admin */ address public pendingAdmin; /** @notice Total amount of stkAAVE rented to Pod Managers */ uint256 public totalRentedAmount; /** @notice Pod Manager states */ mapping(address => PodsManager) public podManagers; /** @notice Address receiving the delegated voting power from the Vault */ address public votingPowerManager; /** @notice Address receiving the delegated proposal power from the Vault */ address public proposalPowerManager; /** @notice Percentage of funds to stay in the contract for withdraws */ uint256 public bufferRatio = 500; /** @notice Amount accrued as Reserve */ uint256 public reserveAmount; /** @notice Ratio of claimed rewards to be set as Reserve */ uint256 public reserveRatio; /** @notice Address of the Reserve Manager */ address public reserveManager; // Events /** @notice Event emitted when the Vault is initialized */ event Initialized(); /** @notice Event emitted when stkAAVE is rented to a Pod */ event RentToPod(address indexed manager, address indexed pod, uint256 amount); /** @notice Event emitted when stkAAVE claim is notified by a Pod */ event NotifyRentedAmount(address indexed manager, address indexed pod, uint256 addedAmount); /** @notice Event emitted when stkAAVE is pulled back from a Pod */ event PullFromPod(address indexed manager, address indexed pod, uint256 amount); /** @notice Event emitted when the adminship is transfered */ event AdminTransferred( address indexed previousAdmin, address indexed newAdmin ); /** @notice Event emitted when a new pending admin is set */ event NewPendingAdmin( address indexed previousPendingAdmin, address indexed newPendingAdmin ); /** @notice Event emitted when a new Pod Manager is added */ event NewPodManager(address indexed newManager); /** @notice Event emitted when a Pod Manager is blocked */ event BlockedPodManager(address indexed manager); /** @notice Event emitted when depositing in the Reserve */ event ReserveDeposit(address indexed from, uint256 amount); /** @notice Event emitted when withdrawing from the Reserve */ event ReserveWithdraw(address indexed to, uint256 amount); /** @notice Event emitted when the Voting maanger is updated */ event UpdatedVotingPowerManager(address indexed oldManager, address indexed newManager); /** @notice Event emitted when the Proposal maanger is updated */ event UpdatedProposalPowerManager(address indexed oldManager, address indexed newManager); /** @notice Event emitted when the Reserve manager is updated */ event UpdatedReserveManager(address indexed oldManager, address indexed newManager); /** @notice Event emitted when the Buffer ratio is updated */ event UpdatedBufferRatio(uint256 oldRatio, uint256 newRatio); /** @notice Event emitted when the Reserve ratio is updated */ event UpdatedReserveRatio(uint256 oldRatio, uint256 newRatio); /** @notice Event emitted when an ERC20 token is recovered */ event TokenRecovered(address indexed token, uint256 amount); // Modifers /** @notice Check that the caller is the admin */ modifier onlyAdmin() { if (msg.sender != admin) revert Errors.CallerNotAdmin(); _; } /** @notice Check that the caller is the admin or the Reserve maanger */ modifier onlyAllowed() { if (msg.sender != admin && msg.sender != reserveManager) revert Errors.CallerNotAdmin(); _; } /** @notice Check that the contract is initialized */ modifier isInitialized() { if (!initialized) revert Errors.NotInitialized(); _; } // Constructor constructor( address _admin, uint256 _reserveRatio, address _reserveManager, address _aave, address _stkAave, string memory _name, string memory _symbol ) ScalingERC20(_name, _symbol) { if(_admin == address(0) || _reserveManager == address(0) || _aave == address(0) || _stkAave == address(0)) revert Errors.AddressZero(); if(_reserveRatio == 0) revert Errors.NullAmount(); admin = _admin; reserveRatio = _reserveRatio; reserveManager = _reserveManager; AAVE = _aave; STK_AAVE = _stkAave; } /** * @notice Initialize the Vault * @dev Initialize the Vault by performing a seed deposit & delegating voting power * @param _votingPowerManager Address to receive the voting power delegation * @param _proposalPowerManager Address to receive the proposal power delegation */ function init(address _votingPowerManager, address _proposalPowerManager) external onlyAdmin { if(initialized) revert Errors.AlreadyInitialized(); initialized = true; votingPowerManager = _votingPowerManager; proposalPowerManager = _proposalPowerManager; // Seed deposit to prevent 1 wei LP token exploit _deposit( SEED_DEPOSIT, msg.sender, msg.sender ); // Set the delegates, so any received token updates the delegates power IGovernancePowerDelegationToken(STK_AAVE).delegateByType( _votingPowerManager, IGovernancePowerDelegationToken.DelegationType.VOTING_POWER ); IGovernancePowerDelegationToken(STK_AAVE).delegateByType( _proposalPowerManager, IGovernancePowerDelegationToken.DelegationType.PROPOSITION_POWER ); emit Initialized(); } // View functions /** * @notice Get the vault's asset * @return address : Address of the asset */ function asset() external view returns (address) { return STK_AAVE; } /** * @notice Get the total amount of assets in the Vault * @return uint256 : total amount of assets */ function totalAssets() public view returns (uint256) { return IERC20(STK_AAVE).balanceOf(address(this)) + totalRentedAmount - reserveAmount; } /** * @notice Get the total supply of shares * @return uint256 : Total supply of shares */ function totalSupply() public view override(ScalingERC20, IERC20) returns (uint256) { return totalAssets(); } /** * @notice Get the current total amount of asset available in the Vault * @return uint256 : Current total amount available */ function totalAvailable() public view returns (uint256) { uint256 availableBalance = IERC20(STK_AAVE).balanceOf(address(this)); availableBalance = reserveAmount >= availableBalance ? 0 : availableBalance - reserveAmount; uint256 bufferAmount = (totalAssets() * bufferRatio) / MAX_BPS; return availableBalance > bufferAmount ? availableBalance - bufferAmount : 0; } /** * @notice Convert a given amount of assets to shares * @param assets amount of assets * @return uint256 : amount of shares */ function convertToShares(uint256 assets) public pure returns (uint256) { // Because we use a ScalingERC20, shares of the user will grow over time to match the owed assets // (assets & shares are always 1:1) return assets; } /** * @notice Convert a given amount of shares to assets * @param shares amount of shares * @return uint256 : amount of assets */ function convertToAssets(uint256 shares) public pure returns (uint256) { // Because we use a ScalingERC20, shares of the user will grow over time to match the owed assets // (assets & shares are always 1:1) return shares; } /** * @notice Return the amount of shares expected for depositing the given assets * @param assets Amount of assets to be deposited * @return uint256 : amount of shares */ function previewDeposit(uint256 assets) public pure returns (uint256) { // Because we use a ScalingERC20, shares of the user will grow over time to match the owed assets // (assets & shares are always 1:1) return assets; } /** * @notice Return the amount of assets expected for minting the given shares * @param shares Amount of shares to be minted * @return uint256 : amount of assets */ function previewMint(uint256 shares) public pure returns (uint256) { // Because we use a ScalingERC20, shares of the user will grow over time to match the owed assets // (assets & shares are always 1:1) return shares; } /** * @notice Return the amount of shares expected for withdrawing the given assets * @param assets Amount of assets to be withdrawn * @return uint256 : amount of shares */ function previewWithdraw(uint256 assets) public pure returns (uint256) { // Because we use a ScalingERC20, shares of the user will grow over time to match the owed assets // (assets & shares are always 1:1) return assets; } /** * @notice Return the amount of assets expected for burning the given shares * @param shares Amount of shares to be burned * @return uint256 : amount of assets */ function previewRedeem(uint256 shares) public pure returns (uint256) { // Because we use a ScalingERC20, shares of the user will grow over time to match the owed assets // (assets & shares are always 1:1) return shares; } /** * @notice Get the maximum amount that can be deposited by the user * @param user User address * @return uint256 : Max amount to deposit */ function maxDeposit(address user) public view returns (uint256) { return type(uint256).max; } /** * @notice Get the maximum amount that can be minted by the user * @param user User address * @return uint256 : Max amount to mint */ function maxMint(address user) public view returns (uint256) { return type(uint256).max; } /** * @notice Get the maximum amount that can be withdrawn by the user * @param owner Owner address * @return uint256 : Max amount to withdraw */ function maxWithdraw(address owner) public view returns (uint256) { return balanceOf(owner); } /** * @notice Get the maximum amount that can be burned by the user * @param owner Owner address * @return uint256 : Max amount to burn */ function maxRedeem(address owner) public view returns (uint256) { return balanceOf(owner); } /** * @notice Get the current index to convert between balance and scaled balances * @return uint256 : Current index */ function getCurrentIndex() public view returns(uint256) { return _getCurrentIndex(); } /** * @notice Get the current delegates for the Vault voting power & proposal power */ function getDelegates() external view returns(address votingPower, address proposalPower) { return (votingPowerManager, proposalPowerManager); } // State-changing functions /** * @notice Deposit assets in the Vault & mint shares * @param assets Amount to deposit * @param receiver Address to receive the shares * @return shares - uint256 : Amount of shares minted */ function deposit( uint256 assets, address receiver ) public isInitialized nonReentrant whenNotPaused returns (uint256 shares) { (assets, shares) = _deposit(assets, receiver, msg.sender); emit Deposit(msg.sender, receiver, assets, shares); } /** * @notice Mint vault shares by depositing assets * @param shares Amount of shares to mint * @param receiver Address to receive the shares * @return assets - uint256 : Amount of assets deposited */ function mint( uint256 shares, address receiver ) public isInitialized nonReentrant whenNotPaused returns (uint256 assets) { (assets, shares) = _deposit(shares, receiver, msg.sender); emit Deposit(msg.sender, receiver, assets, shares); } /** * @notice Withdraw from the Vault & burn shares * @param assets Amount of assets to withdraw * @param receiver Address to receive the assets * @param owner Address of the owner of the shares * @return shares - uint256 : Amount of shares burned */ function withdraw( uint256 assets, address receiver, address owner ) public isInitialized nonReentrant returns (uint256 shares) { (uint256 _withdrawn, uint256 _burntShares) = _withdraw( assets, owner, receiver, msg.sender ); emit Withdraw(msg.sender, receiver, owner, _withdrawn, _burntShares); return _burntShares; } /** * @notice Burn shares to withdraw from the Vault * @param shares Amount of shares to burn * @param receiver Address to receive the assets * @param owner Address of the owner of the shares * @return assets - uint256 : Amount of assets withdrawn */ function redeem( uint256 shares, address receiver, address owner ) public isInitialized nonReentrant returns (uint256 assets) { (uint256 _withdrawn, uint256 _burntShares) = _withdraw( shares, owner, receiver, msg.sender ); emit Withdraw(msg.sender, receiver, owner, _withdrawn, _burntShares); return _withdrawn; } /** * @notice Claim Safety Module rewards & stake them in stkAAVE */ function updateStkAaveRewards() external nonReentrant { _getStkAaveRewards(); } // Pods Manager functions /** * @notice Rent stkAAVE for a Pod * @dev Rent stkAAVE to a Pod, sending the amount & tracking the manager that requested * @param pod Address of the Pod * @param amount Amount to rent */ function rentStkAave(address pod, uint256 amount) external nonReentrant { address manager = msg.sender; if(!podManagers[manager].rentingAllowed) revert Errors.CallerNotAllowedManager(); if(pod == address(0)) revert Errors.AddressZero(); if(amount == 0) revert Errors.NullAmount(); // Fetch Aave Safety Module rewards & stake them into stkAAVE _getStkAaveRewards(); IERC20 _stkAave = IERC20(STK_AAVE); // Check that the asked amount is available : // - Vault has enough asset for the asked amount // - Asked amount does not include the buffer allocated to withdraws uint256 availableBalance = _stkAave.balanceOf(address(this)); availableBalance = reserveAmount >= availableBalance ? 0 : availableBalance - reserveAmount; uint256 bufferAmount = (totalAssets() * bufferRatio) / MAX_BPS; if(availableBalance < bufferAmount) revert Errors.WithdrawBuffer(); if(amount > (availableBalance - bufferAmount)) revert Errors.NotEnoughAvailableFunds(); // Track the amount rented for the manager that requested it // & send the token to the Pod podManagers[manager].totalRented += safe248(amount); totalRentedAmount += amount; _stkAave.safeTransfer(pod, amount); emit RentToPod(manager, pod, amount); } /** * @notice Notify a claim on rented stkAAVE * @dev Notify the newly claimed rewards from rented stkAAVE to a Pod & add it as rented to the Pod * @param pod Address of the Pod * @param addedAmount Amount added */ // To track pods stkAave claims & re-stake into the main balance for ScalingeRC20 logic function notifyRentedAmount(address pod, uint256 addedAmount) external nonReentrant { address manager = msg.sender; if(podManagers[manager].totalRented == 0) revert Errors.NotUndebtedManager(); if(pod == address(0)) revert Errors.AddressZero(); if(addedAmount == 0) revert Errors.NullAmount(); // Update the total amount rented & the amount rented for the specific // maanger with the amount claimed from Aave's Safety Module via the Pod podManagers[manager].totalRented += safe248(addedAmount); totalRentedAmount += addedAmount; // Add the part taken as fees to the Reserve reserveAmount += (addedAmount * reserveRatio) / MAX_BPS; emit NotifyRentedAmount(manager, pod, addedAmount); } /** * @notice Pull rented stkAAVE from a Pod * @dev Pull stkAAVE from a Pod & update the tracked rented amount * @param pod Address of the Pod * @param amount Amount to pull */ function pullRentedStkAave(address pod, uint256 amount) external nonReentrant { address manager = msg.sender; if(podManagers[manager].totalRented == 0) revert Errors.NotUndebtedManager(); if(pod == address(0)) revert Errors.AddressZero(); if(amount == 0) revert Errors.NullAmount(); if(amount > podManagers[manager].totalRented) revert Errors.AmountExceedsDebt(); // Fetch Aave Safety Module rewards & stake them into stkAAVE _getStkAaveRewards(); // Pull the tokens from the Pod, and update the tracked rented amount for the // corresponding Manager podManagers[manager].totalRented -= safe248(amount); totalRentedAmount -= amount; // We consider that pod give MAX_UINT256 allowance to this contract when created IERC20(STK_AAVE).safeTransferFrom(pod, address(this), amount); emit PullFromPod(manager, pod, amount); } // Internal functions /** * @dev Get the current index to convert between balance and scaled balances * @return uint256 : Current index */ function _getCurrentIndex() internal view override returns (uint256) { if(_totalSupply == 0) return INITIAL_INDEX; return totalAssets().rayDiv(_totalSupply); } /** * @dev Pull assets to deposit in the Vault & mint shares * @param amount Amount to deposit * @param receiver Address to receive the shares * @param depositor Address depositing the assets * @return uint256 : Amount of assets deposited * @return uint256 : Amount of shares minted */ function _deposit( uint256 amount, address receiver, address depositor ) internal returns (uint256, uint256) { if (receiver == address(0)) revert Errors.AddressZero(); if (amount == 0) revert Errors.NullAmount(); // Fetch Aave Safety Module rewards & stake them into stkAAVE _getStkAaveRewards(); // We need to get the index before pulling the assets // so we can have the correct one based on previous stkAave claim uint256 _currentIndex = _getCurrentIndex(); // Pull tokens from the depositor IERC20(STK_AAVE).safeTransferFrom(depositor, address(this), amount); // Mint the scaled balance of the user to match the deposited amount uint256 minted = _mint(receiver, amount, _currentIndex); afterDeposit(amount); return (amount, minted); } /** * @dev Withdraw assets from the Vault & send to the receiver & burn shares * @param amount Amount to withdraw * @param owner Address owning the shares * @param receiver Address to receive the assets * @param sender Address of the caller * @return uint256 : Amount of assets withdrawn * @return uint256 : Amount of shares burned */ function _withdraw( uint256 amount, // if `MAX_UINT256`, just withdraw everything address owner, address receiver, address sender ) internal returns (uint256, uint256) { if (receiver == address(0) || owner == address(0)) revert Errors.AddressZero(); if (amount == 0) revert Errors.NullAmount(); // Fetch Aave Safety Module rewards & stake them into stkAAVE _getStkAaveRewards(); // If the user wants to withdraw their full balance bool _maxWithdraw; if(amount == MAX_UINT256) { amount = balanceOf(owner); _maxWithdraw = true; } // Check that the caller has the allowance to withdraw for the given owner if (owner != sender) { uint256 allowed = _allowances[owner][sender]; if (allowed < amount) revert Errors.ERC20_AmountOverAllowance(); if (allowed != type(uint256).max) _allowances[owner][sender] = allowed - amount; } IERC20 _stkAave = IERC20(STK_AAVE); // Check that the Vault has enough stkAave to send uint256 availableBalance = _stkAave.balanceOf(address(this)); availableBalance = reserveAmount >= availableBalance ? 0 : availableBalance - reserveAmount; if(amount > availableBalance) revert Errors.NotEnoughAvailableFunds(); // Burn the scaled balance matching the amount to withdraw uint256 burned = _burn(owner, amount, _maxWithdraw); beforeWithdraw(amount); // Send the tokens to the given receiver _stkAave.safeTransfer(receiver, amount); return (amount, burned); } /** * @dev Hook exectued before withdrawing * @param amount Amount to withdraw */ function beforeWithdraw(uint256 amount) internal {} /** * @dev Hook exectued after depositing * @param amount Amount deposited */ function afterDeposit(uint256 amount) internal {} /** * @dev Hook executed before each transfer * @param from Sender address * @param to Receiver address * @param amount Amount to transfer */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal isInitialized whenNotPaused override virtual { super._beforeTokenTransfer(from, to, amount); } /** * @dev Hook executed after each transfer * @param from Sender address * @param to Receiver address * @param amount Amount to transfer */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal override virtual { super._afterTokenTransfer(from, to, amount); } /** * @dev Claim AAVE rewards from the Safety Module & stake them to receive stkAAVE */ function _getStkAaveRewards() internal { IStakedAave _stkAave = IStakedAave(STK_AAVE); // Get pending rewards amount uint256 pendingRewards = _stkAave.getTotalRewardsBalance(address(this)); if (pendingRewards > 0) { // Claim the AAVE tokens _stkAave.claimRewards(address(this), pendingRewards); // Set a part of the claimed amount as the Reserve (protocol fees) reserveAmount += (pendingRewards * reserveRatio) / MAX_BPS; } IERC20 _aave = IERC20(AAVE); uint256 currentBalance = _aave.balanceOf(address(this)); if(currentBalance > 0) { // Increase allowance for the Safety Module & stake AAVE into stkAAVE _aave.safeIncreaseAllowance(STK_AAVE, currentBalance); _stkAave.stake(address(this), currentBalance); } } // Admin /** * @notice Pause the contract */ function pause() external onlyAdmin { _pause(); } /** * @notice Unpause the contract */ function unpause() external onlyAdmin { _unpause(); } /** * @notice Set a given address as the new pending admin * @param newAdmin Address to be the new admin */ function transferAdmin(address newAdmin) external onlyAdmin { if (newAdmin == address(0)) revert Errors.AddressZero(); if (newAdmin == admin) revert Errors.CannotBeAdmin(); address oldPendingAdmin = pendingAdmin; pendingAdmin = newAdmin; emit NewPendingAdmin(oldPendingAdmin, newAdmin); } /** * @notice Accpet adminship of the contract (must be the pending admin) */ function acceptAdmin() external { if (msg.sender != pendingAdmin) revert Errors.CallerNotPendingAdmin(); address newAdmin = pendingAdmin; address oldAdmin = admin; admin = newAdmin; pendingAdmin = address(0); emit AdminTransferred(oldAdmin, newAdmin); emit NewPendingAdmin(newAdmin, address(0)); } /** * @notice Add a new Pod Manager * @param newManager Address of the new manager */ function addPodManager(address newManager) external onlyAdmin { if(newManager == address(0)) revert Errors.AddressZero(); if(podManagers[newManager].rentingAllowed) revert Errors.ManagerAlreadyListed(); podManagers[newManager].rentingAllowed = true; emit NewPodManager(newManager); } /** * @notice Block a Pod Manager * @param manager Address of the manager */ function blockPodManager(address manager) external onlyAdmin { if(manager == address(0)) revert Errors.AddressZero(); if(!podManagers[manager].rentingAllowed) revert Errors.ManagerNotListed(); podManagers[manager].rentingAllowed = false; emit BlockedPodManager(manager); } /** * @notice Update the Vault's voting power manager & delegate the voting power to it * @param newManager Address of the new manager */ function updateVotingPowerManager(address newManager) external onlyAdmin { if(newManager == address(0)) revert Errors.AddressZero(); if(newManager == votingPowerManager) revert Errors.SameAddress(); address oldManager = votingPowerManager; votingPowerManager = newManager; IGovernancePowerDelegationToken(STK_AAVE).delegateByType( newManager, IGovernancePowerDelegationToken.DelegationType.VOTING_POWER ); emit UpdatedVotingPowerManager(oldManager, newManager); } /** * @notice Update the Vault's proposal power manager & delegate the proposal power to it * @param newManager Address of the new manager */ function updateProposalPowerManager(address newManager) external onlyAdmin { if(newManager == address(0)) revert Errors.AddressZero(); if(newManager == proposalPowerManager) revert Errors.SameAddress(); address oldManager = proposalPowerManager; proposalPowerManager = newManager; IGovernancePowerDelegationToken(STK_AAVE).delegateByType( newManager, IGovernancePowerDelegationToken.DelegationType.PROPOSITION_POWER ); emit UpdatedProposalPowerManager(oldManager, newManager); } /** * @notice Update the Vault's Reserve manager * @param newManager Address of the new manager */ function updateReserveManager(address newManager) external onlyAdmin { if(newManager == address(0)) revert Errors.AddressZero(); if(newManager == reserveManager) revert Errors.SameAddress(); address oldManager = reserveManager; reserveManager = newManager; emit UpdatedReserveManager(oldManager, newManager); } /** * @notice Uodate the reserve ratio parameter * @param newRatio New ratio value */ function updateReserveRatio(uint256 newRatio) external onlyAdmin { if(newRatio > 1500) revert Errors.InvalidParameter(); uint256 oldRatio = reserveRatio; reserveRatio = newRatio; emit UpdatedReserveRatio(oldRatio, newRatio); } /** * @notice Uodate the buffer ratio parameter * @param newRatio New ratio value */ function updateBufferRatio(uint256 newRatio) external onlyAdmin { if(newRatio > 1500) revert Errors.InvalidParameter(); uint256 oldRatio = bufferRatio; bufferRatio = newRatio; emit UpdatedBufferRatio(oldRatio, newRatio); } /** * @notice Deposit token in the reserve * @param amount Amount of token to deposit */ function depositToReserve(uint256 amount) external nonReentrant onlyAllowed returns(bool) { if(amount == 0) revert Errors.NullAmount(); // Fetch Aave Safety Module rewards & stake them into stkAAVE _getStkAaveRewards(); IERC20(STK_AAVE).safeTransferFrom(msg.sender, address(this), amount); reserveAmount += amount; emit ReserveDeposit(msg.sender, amount); return true; } /** * @notice Withdraw tokens from the reserve to send to the given receiver * @param amount Amount of token to withdraw * @param receiver Address to receive the tokens */ function withdrawFromReserve(uint256 amount, address receiver) external nonReentrant onlyAllowed returns(bool) { if(amount == 0) revert Errors.NullAmount(); if(receiver == address(0)) revert Errors.AddressZero(); if(amount > reserveAmount) revert Errors.ReserveTooLow(); // Fetch Aave Safety Module rewards & stake them into stkAAVE _getStkAaveRewards(); IERC20(STK_AAVE).safeTransfer(receiver, amount); reserveAmount -= amount; emit ReserveWithdraw(receiver, amount); return true; } /** * @notice Recover ERC2O tokens sent by mistake to the contract * @dev Recover ERC2O tokens sent by mistake to the contract * @param token Address of the ERC2O token * @return bool: success */ function recoverERC20(address token) external onlyAdmin returns(bool) { if(token == AAVE || token == STK_AAVE) revert Errors.CannotRecoverToken(); uint256 amount = IERC20(token).balanceOf(address(this)); if(amount == 0) revert Errors.NullAmount(); IERC20(token).safeTransfer(admin, amount); emit TokenRecovered(token, amount); return true; } // Maths function safe248(uint256 n) internal pure returns (uint248) { if(n > type(uint248).max) revert Errors.NumberExceed248Bits(); return uint248(n); } }
//██████╗ █████╗ ██╗ █████╗ ██████╗ ██╗███╗ ██╗ //██╔══██╗██╔══██╗██║ ██╔══██╗██╔══██╗██║████╗ ██║ //██████╔╝███████║██║ ███████║██║ ██║██║██╔██╗ ██║ //██╔═══╝ ██╔══██║██║ ██╔══██║██║ ██║██║██║╚██╗██║ //██║ ██║ ██║███████╗██║ ██║██████╔╝██║██║ ╚████║ //╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═════╝ ╚═╝╚═╝ ╚═══╝ pragma solidity 0.8.16; //SPDX-License-Identifier: BUSL-1.1 import "../oz/interfaces/IERC20.sol"; import "../oz/utils/Context.sol"; import {Errors} from "../utils/Errors.sol"; import {WadRayMath} from "../utils/WadRayMath.sol"; /** @title ScalingERC20 contract * @author Paladin, inspired by Aave & OpenZeppelin implementations * @notice ERC20 implementation of scaled balance token */ abstract contract ScalingERC20 is Context, IERC20 { using WadRayMath for uint256; // Constants /** @notice 1e18 scale */ uint256 public constant UNIT = 1e18; /** @notice 1e27 - RAY - Initial Index for balance to scaled balance */ uint256 internal constant INITIAL_INDEX = 1e27; // Structs /** @notice UserState struct * scaledBalance: scaled balance of the user * index: last index for the user */ struct UserState { uint128 scaledBalance; uint128 index; } // Storage /** @notice Total scaled supply */ uint256 internal _totalSupply; /** @notice Allowances for users */ mapping(address => mapping(address => uint256)) internal _allowances; /** @notice Token name */ string private _name; /** @notice Token symbol */ string private _symbol; /** @notice Token decimals */ uint8 private _decimals; /** @notice User states */ mapping(address => UserState) internal _userStates; // Events /** @notice Event emitted when minting */ event Mint(address indexed user, uint256 scaledAmount, uint256 index); /** @notice Event emitted when burning */ event Burn(address indexed user, uint256 scaledAmount, uint256 index); // Constructor constructor( string memory __name, string memory __symbol ) { _name = __name; _symbol = __symbol; _decimals = 18; } // View methods /** * @notice Get the name of the ERC20 * @return string : Name */ function name() public view returns (string memory) { return _name; } /** * @notice Get the symbol of the ERC20 * @return string : Symbol */ function symbol() external view returns (string memory) { return _symbol; } /** * @notice Get the decimals of the ERC20 * @return uint256 : Number of decimals */ function decimals() external view returns (uint8) { return _decimals; } /** * @notice Get the current total supply * @return uint256 : Current total supply */ function totalSupply() public view override virtual returns (uint256) { uint256 _scaledSupply = _totalSupply; if(_scaledSupply == 0) return 0; return _scaledSupply.rayMul(_getCurrentIndex()); } /** * @notice Get the current user balance * @param account Address of user * @return uint256 : User balance */ function balanceOf(address account) public view override virtual returns (uint256) { return uint256(_userStates[account].scaledBalance).rayMul(_getCurrentIndex()); } /** * @notice Get the current total scaled supply * @return uint256 : Current total scaled supply */ function totalScaledSupply() public view virtual returns (uint256) { return _totalSupply; } /** * @notice Get the current user scaled balance * @param account Address of user * @return uint256 : User scaled balance */ function scaledBalanceOf(address account) public view virtual returns (uint256) { return _userStates[account].scaledBalance; } /** * @notice Get the allowance of a spender for a given owner * @param owner Address of the owner * @param spender Address of the spender * @return uint256 : allowance amount */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } // Write methods /** * @notice Approve a spender to spend tokens * @param spender Address of the spender * @param amount Amount to approve * @return bool : success */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(msg.sender, spender, amount); return true; } /** * @notice Increase the allowance given to a spender * @param spender Address of the spender * @param addedValue Increase amount * @return bool : success */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = msg.sender; _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @notice Decrease the allowance given to a spender * @param spender Address of the spender * @param subtractedValue Decrease amount * @return bool : success */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = msg.sender; uint256 currentAllowance = allowance(owner, spender); if(currentAllowance < subtractedValue) revert Errors.ERC20_AllowanceUnderflow(); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @notice Transfer tokens to the given recipient * @param recipient Address to receive the tokens * @param amount Amount to transfer * @return bool : success */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(msg.sender, recipient, amount); emit Transfer(msg.sender, recipient, amount); return true; } /** * @notice Transfer tokens from the spender to the given recipient * @param sender Address sending the tokens * @param recipient Address to receive the tokens * @param amount Amount to transfer * @return bool : success */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { uint256 _allowance = _allowances[sender][msg.sender]; if(_allowance < amount) revert Errors.ERC20_AmountOverAllowance(); if(_allowance != type(uint256).max) { _approve( sender, msg.sender, _allowances[sender][msg.sender] - amount ); } _transfer(sender, recipient, amount); emit Transfer(sender, recipient, amount); return true; } // Internal methods /** * @dev Get the current index to convert between balance and scaled balances * @return uint256 : Current index */ // To implement in inheriting contract function _getCurrentIndex() internal virtual view returns(uint256) {} /** * @dev Approve a spender to spend tokens * @param owner Address of the woner * @param spender Address of the spender * @param amount Amount to approve */ function _approve( address owner, address spender, uint256 amount ) internal virtual { if(owner == address(0) || spender == address(0)) revert Errors.ERC20_ApproveAddressZero(); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Transfer tokens from the spender to the given recipient * @param sender Address sending the tokens * @param recipient Address to receive the tokens * @param amount Amount to transfer */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { if(sender == address(0) || recipient == address(0)) revert Errors.ERC20_AddressZero(); if(sender == recipient) revert Errors.ERC20_SelfTransfer(); if(amount == 0) revert Errors.ERC20_NullAmount(); // Get the scaled amount to transfer for the given amount uint128 _scaledAmount = safe128(amount.rayDiv(_getCurrentIndex())); _transferScaled(sender, recipient, _scaledAmount); } /** * @dev Transfer the scaled amount of tokens * @param sender Address sending the tokens * @param recipient Address to receive the tokens * @param scaledAmount Scaled amount to transfer */ function _transferScaled( address sender, address recipient, uint128 scaledAmount ) internal virtual { if(scaledAmount > _userStates[sender].scaledBalance) revert Errors.ERC20_AmountExceedBalance(); _beforeTokenTransfer(sender, recipient, scaledAmount); unchecked { // Should never fail because of previous check // & because the scaledBalance of an user should never exceed the _totalSupply _userStates[sender].scaledBalance -= scaledAmount; _userStates[recipient].scaledBalance += scaledAmount; } _afterTokenTransfer(sender, recipient, scaledAmount); } /** * @dev Mint the given amount to the given address (by minting the correct scaled amount) * @param account Address to mint to * @param amount Amount to mint * @param _currentIndex Index to use to calculate the scaled amount * @return uint256 : Amount minted */ function _mint(address account, uint256 amount, uint256 _currentIndex) internal virtual returns(uint256) { uint256 _scaledAmount = amount.rayDiv(_currentIndex); if(_scaledAmount == 0) revert Errors.ERC20_NullAmount(); _beforeTokenTransfer(address(0), account, _scaledAmount); _userStates[account].index = safe128(_currentIndex); _totalSupply += _scaledAmount; _userStates[account].scaledBalance += safe128(_scaledAmount); _afterTokenTransfer(address(0), account, _scaledAmount); emit Mint(account, _scaledAmount, _currentIndex); emit Transfer(address(0), account, amount); return amount; } /** * @dev Burn the given amount from the given address (by burning the correct scaled amount) * @param account Address to burn from * @param amount Amount to burn * @param maxWithdraw True if burning the full balance * @return uint256 : Amount burned */ function _burn(address account, uint256 amount, bool maxWithdraw) internal virtual returns(uint256) { uint256 _currentIndex = _getCurrentIndex(); uint256 _scaledBalance = _userStates[account].scaledBalance; // if given maxWithdraw as true, we want to burn the whole balance for the user uint256 _scaledAmount = maxWithdraw ? _scaledBalance: amount.rayDiv(_currentIndex); if(_scaledAmount == 0) revert Errors.ERC20_NullAmount(); if(_scaledAmount > _scaledBalance) revert Errors.ERC20_AmountExceedBalance(); _beforeTokenTransfer(account, address(0), _scaledAmount); _userStates[account].index = safe128(_currentIndex); _totalSupply -= _scaledAmount; _userStates[account].scaledBalance -= safe128(_scaledAmount); _afterTokenTransfer(account, address(0), _scaledAmount); emit Burn(account, _scaledAmount, _currentIndex); emit Transfer(account, address(0), amount); return amount; } // Virtual hooks /** * @dev Hook executed before each transfer * @param from Sender address * @param to Receiver address * @param amount Amount to transfer */ // To implement in inheriting contract function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook executed after each transfer * @param from Sender address * @param to Receiver address * @param amount Amount to transfer */ // To implement in inheriting contract function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} // Maths function safe128(uint256 n) internal pure returns (uint128) { if(n > type(uint128).max) revert Errors.NumberExceed128Bits(); return uint128(n); } }
pragma solidity 0.8.16; //SPDX-License-Identifier: MIT import "../oz/interfaces/IERC20.sol"; interface IERC4626 is IERC20 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Deposit( address indexed caller, address indexed owner, uint256 assets, uint256 shares ); event Withdraw( address indexed caller, address indexed receiver, address indexed owner, uint256 assets, uint256 shares ); /*////////////////////////////////////////////////////////////// IMMUTABLES //////////////////////////////////////////////////////////////*/ function asset() external view returns (address); /*////////////////////////////////////////////////////////////// DEPOSIT/WITHDRAWAL LOGIC //////////////////////////////////////////////////////////////*/ function deposit(uint256 assets, address receiver) external returns (uint256 shares); function mint(uint256 shares, address receiver) external returns (uint256 assets); function withdraw( uint256 assets, address receiver, address owner ) external returns (uint256 shares); function redeem( uint256 shares, address receiver, address owner ) external returns (uint256 assets); /*////////////////////////////////////////////////////////////// ACCOUNTING LOGIC //////////////////////////////////////////////////////////////*/ function totalAssets() external view returns (uint256); function convertToShares(uint256 assets) external view returns (uint256); function convertToAssets(uint256 shares) external view returns (uint256); function previewDeposit(uint256 assets) external view returns (uint256); function previewMint(uint256 shares) external view returns (uint256); function previewWithdraw(uint256 assets) external view returns (uint256); function previewRedeem(uint256 shares) external view returns (uint256); /*////////////////////////////////////////////////////////////// DEPOSIT/WITHDRAWAL LIMIT LOGIC //////////////////////////////////////////////////////////////*/ function maxDeposit(address) external view returns (uint256); function maxMint(address) external view returns (uint256); function maxWithdraw(address owner) external view returns (uint256); function maxRedeem(address owner) external view returns (uint256); /*////////////////////////////////////////////////////////////// INTERNAL HOOKS LOGIC //////////////////////////////////////////////////////////////*/ /* function beforeWithdraw(uint256 assets, uint256 shares) internal {} function afterDeposit(uint256 assets, uint256 shares) internal {} */ }
//Aave Governance Token Interface // SPDX-License-Identifier: agpl-3.0 pragma solidity 0.8.16; interface IGovernancePowerDelegationToken { enum DelegationType { VOTING_POWER, PROPOSITION_POWER } /** * @dev emitted when a user delegates to another * @param delegator the delegator * @param delegatee the delegatee * @param delegationType the type of delegation (VOTING_POWER, PROPOSITION_POWER) **/ event DelegateChanged( address indexed delegator, address indexed delegatee, DelegationType delegationType ); /** * @dev emitted when an action changes the delegated power of a user * @param user the user which delegated power has changed * @param amount the amount of delegated power for the user * @param delegationType the type of delegation (VOTING_POWER, PROPOSITION_POWER) **/ event DelegatedPowerChanged( address indexed user, uint256 amount, DelegationType delegationType ); /** * @dev delegates the specific power to a delegatee * @param delegatee the user which delegated power has changed * @param delegationType the type of delegation (VOTING_POWER, PROPOSITION_POWER) **/ function delegateByType(address delegatee, DelegationType delegationType) external; /** * @dev delegates all the powers to a specific user * @param delegatee the user to which the power will be delegated **/ function delegate(address delegatee) external; /** * @dev returns the delegatee of an user * @param delegator the address of the delegator **/ function getDelegateeByType( address delegator, DelegationType delegationType ) external view returns (address); /** * @dev returns the current delegated power of a user. The current power is the * power delegated at the time of the last snapshot * @param user the user **/ function getPowerCurrent(address user, DelegationType delegationType) external view returns (uint256); /** * @dev returns the delegated power of a user at a certain block * @param user the user **/ function getPowerAtBlock( address user, uint256 blockNumber, DelegationType delegationType ) external view returns (uint256); /** * @dev returns the total supply at a certain block number **/ function totalSupplyAt(uint256 blockNumber) external view returns (uint256); }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.8.16; interface IStakedAave { event Staked( address indexed from, address indexed to, uint256 assets, uint256 shares ); event Redeem( address indexed from, address indexed to, uint256 assets, uint256 shares ); event RewardsAccrued(address user, uint256 amount); event RewardsClaimed(address indexed from, address indexed to, uint256 amount); event Cooldown(address indexed user); function stake(address to, uint256 amount) external; function redeem(address to, uint256 amount) external; function cooldown() external; function claimRewards(address to, uint256 amount) external; function getTotalRewardsBalance(address staker) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../interfaces/IERC20.sol"; import "../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return 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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @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 v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/Pausable.sol) pragma solidity ^0.8.0; import "./Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (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() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
pragma solidity 0.8.16; //SPDX-License-Identifier: MIT library Errors { // Common Errors error AddressZero(); error NullAmount(); error IncorrectRewardToken(); error SameAddress(); error InequalArraySizes(); error EmptyArray(); error EmptyParameters(); error NotInitialized(); error AlreadyInitialized(); error CannotInitialize(); error InvalidParameter(); error CannotRecoverToken(); error NullWithdraw(); error AlreadyListedManager(); error NotListedManager(); // Access Control Erros error CallerNotAdmin(); error CannotBeAdmin(); error CallerNotPendingAdmin(); error CallerNotAllowed(); // ERC20 Errors error ERC20_ApproveAddressZero(); error ERC20_AllowanceUnderflow(); error ERC20_AmountOverAllowance(); error ERC20_AddressZero(); error ERC20_SelfTransfer(); error ERC20_NullAmount(); error ERC20_AmountExceedBalance(); // Maths Errors error NumberExceed96Bits(); error NumberExceed128Bits(); error NumberExceed248Bits(); // Vault Errors error ManagerAlreadyListed(); error ManagerNotListed(); error NotEnoughAvailableFunds(); error WithdrawBuffer(); error ReserveTooLow(); error CallerNotAllowedManager(); error NotUndebtedManager(); error AmountExceedsDebt(); // Vaults Rewards Errors error NullScaledAmount(); error AlreadyListedDepositor(); error NotListedDepositor(); error ClaimNotAllowed(); // Pods Errors error NotPodOwner(); error NotPodManager(); error FailPodStateUpdate(); error MintAmountUnderMinimum(); error RepayFailed(); // Pods Manager Errors error CallerNotValidPod(); error CollateralBlocked(); error MintingAllowanceFailed(); error FreeingStkAaveFailed(); error CollateralAlreadyListed(); error CollateralNotListed(); error CollateralNotAllowed(); error PodInvalid(); error FailStateUpdate(); error PodNotLiquidable(); // Registry Errors error VaultAlreadySet(); // Zap Errors error InvalidSourceToken(); error DepositFailed(); // Wrapper Errors error NullConvertedAmount(); }
// SPDX-License-Identifier: GNU AGPLv3 pragma solidity ^0.8.0; /// @title WadRayMath. /// @author Morpho Labs. /// @custom:contact [email protected] /// @notice Optimized version of Aave V3 math library WadRayMath to conduct wad and ray manipulations: https://github.com/aave/aave-v3-core/blob/master/contracts/protocol/libraries/math/WadRayMath.sol library WadRayMath { /// CONSTANTS /// uint256 internal constant WAD = 1e18; uint256 internal constant HALF_WAD = 0.5e18; uint256 internal constant RAY = 1e27; uint256 internal constant HALF_RAY = 0.5e27; uint256 internal constant WAD_RAY_RATIO = 1e9; uint256 internal constant HALF_WAD_RAY_RATIO = 0.5e9; uint256 internal constant MAX_UINT256 = 2**256 - 1; // Not possible to use type(uint256).max in yul. uint256 internal constant MAX_UINT256_MINUS_HALF_WAD = 2**256 - 1 - 0.5e18; uint256 internal constant MAX_UINT256_MINUS_HALF_RAY = 2**256 - 1 - 0.5e27; /// INTERNAL /// /// @dev Multiplies two wad, rounding half up to the nearest wad. /// @param x Wad. /// @param y Wad. /// @return z The result of x * y, in wad. function wadMul(uint256 x, uint256 y) internal pure returns (uint256 z) { // Let y > 0 // Overflow if (x * y + HALF_WAD) > type(uint256).max // <=> x * y > type(uint256).max - HALF_WAD // <=> x > (type(uint256).max - HALF_WAD) / y assembly { if mul(y, gt(x, div(MAX_UINT256_MINUS_HALF_WAD, y))) { revert(0, 0) } z := div(add(mul(x, y), HALF_WAD), WAD) } } /// @dev Divides two wad, rounding half up to the nearest wad. /// @param x Wad. /// @param y Wad. /// @return z The result of x / y, in wad. function wadDiv(uint256 x, uint256 y) internal pure returns (uint256 z) { // Overflow if y == 0 // Overflow if (x * WAD + y / 2) > type(uint256).max // <=> x * WAD > type(uint256).max - y / 2 // <=> x > (type(uint256).max - y / 2) / WAD assembly { z := div(y, 2) if iszero(mul(y, iszero(gt(x, div(sub(MAX_UINT256, z), WAD))))) { revert(0, 0) } z := div(add(mul(WAD, x), z), y) } } /// @dev Multiplies two ray, rounding half up to the nearest ray. /// @param x Ray. /// @param y Ray. /// @return z The result of x * y, in ray. function rayMul(uint256 x, uint256 y) internal pure returns (uint256 z) { // Let y > 0 // Overflow if (x * y + HALF_RAY) > type(uint256).max // <=> x * y > type(uint256).max - HALF_RAY // <=> x > (type(uint256).max - HALF_RAY) / y assembly { if mul(y, gt(x, div(MAX_UINT256_MINUS_HALF_RAY, y))) { revert(0, 0) } z := div(add(mul(x, y), HALF_RAY), RAY) } } /// @dev Divides two ray, rounding half up to the nearest ray. /// @param x Ray. /// @param y Ray. /// @return z The result of x / y, in ray. function rayDiv(uint256 x, uint256 y) internal pure returns (uint256 z) { // Overflow if y == 0 // Overflow if (x * RAY + y / 2) > type(uint256).max // <=> x * RAY > type(uint256).max - y / 2 // <=> x > (type(uint256).max - y / 2) / RAY assembly { z := div(y, 2) if iszero(mul(y, iszero(gt(x, div(sub(MAX_UINT256, z), RAY))))) { revert(0, 0) } z := div(add(mul(RAY, x), z), y) } } /// @dev Casts ray down to wad. /// @param x Ray. /// @return y = x converted to wad, rounded half up to the nearest wad. function rayToWad(uint256 x) internal pure returns (uint256 y) { assembly { // If x % WAD_RAY_RATIO >= HALF_WAD_RAY_RATIO, round up. y := add(div(x, WAD_RAY_RATIO), iszero(lt(mod(x, WAD_RAY_RATIO), HALF_WAD_RAY_RATIO))) } } /// @dev Converts wad up to ray. /// @param x Wad. /// @return y = x converted in ray. function wadToRay(uint256 x) internal pure returns (uint256 y) { assembly { y := mul(WAD_RAY_RATIO, x) // Revert if y / WAD_RAY_RATIO != x if iszero(eq(div(y, WAD_RAY_RATIO), x)) { revert(0, 0) } } } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_admin","type":"address"},{"internalType":"uint256","name":"_reserveRatio","type":"uint256"},{"internalType":"address","name":"_reserveManager","type":"address"},{"internalType":"address","name":"_aave","type":"address"},{"internalType":"address","name":"_stkAave","type":"address"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AddressZero","type":"error"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"AmountExceedsDebt","type":"error"},{"inputs":[],"name":"CallerNotAdmin","type":"error"},{"inputs":[],"name":"CallerNotAllowedManager","type":"error"},{"inputs":[],"name":"CallerNotPendingAdmin","type":"error"},{"inputs":[],"name":"CannotBeAdmin","type":"error"},{"inputs":[],"name":"CannotRecoverToken","type":"error"},{"inputs":[],"name":"ERC20_AddressZero","type":"error"},{"inputs":[],"name":"ERC20_AllowanceUnderflow","type":"error"},{"inputs":[],"name":"ERC20_AmountExceedBalance","type":"error"},{"inputs":[],"name":"ERC20_AmountOverAllowance","type":"error"},{"inputs":[],"name":"ERC20_ApproveAddressZero","type":"error"},{"inputs":[],"name":"ERC20_NullAmount","type":"error"},{"inputs":[],"name":"ERC20_SelfTransfer","type":"error"},{"inputs":[],"name":"InvalidParameter","type":"error"},{"inputs":[],"name":"ManagerAlreadyListed","type":"error"},{"inputs":[],"name":"ManagerNotListed","type":"error"},{"inputs":[],"name":"NotEnoughAvailableFunds","type":"error"},{"inputs":[],"name":"NotInitialized","type":"error"},{"inputs":[],"name":"NotUndebtedManager","type":"error"},{"inputs":[],"name":"NullAmount","type":"error"},{"inputs":[],"name":"NumberExceed128Bits","type":"error"},{"inputs":[],"name":"NumberExceed248Bits","type":"error"},{"inputs":[],"name":"ReserveTooLow","type":"error"},{"inputs":[],"name":"SameAddress","type":"error"},{"inputs":[],"name":"WithdrawBuffer","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":true,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"manager","type":"address"}],"name":"BlockedPodManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"scaledAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"scaledAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousPendingAdmin","type":"address"},{"indexed":true,"internalType":"address","name":"newPendingAdmin","type":"address"}],"name":"NewPendingAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newManager","type":"address"}],"name":"NewPodManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"manager","type":"address"},{"indexed":true,"internalType":"address","name":"pod","type":"address"},{"indexed":false,"internalType":"uint256","name":"addedAmount","type":"uint256"}],"name":"NotifyRentedAmount","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"manager","type":"address"},{"indexed":true,"internalType":"address","name":"pod","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PullFromPod","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"manager","type":"address"},{"indexed":true,"internalType":"address","name":"pod","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RentToPod","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ReserveDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ReserveWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokenRecovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldRatio","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newRatio","type":"uint256"}],"name":"UpdatedBufferRatio","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldManager","type":"address"},{"indexed":true,"internalType":"address","name":"newManager","type":"address"}],"name":"UpdatedProposalPowerManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldManager","type":"address"},{"indexed":true,"internalType":"address","name":"newManager","type":"address"}],"name":"UpdatedReserveManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldRatio","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newRatio","type":"uint256"}],"name":"UpdatedReserveRatio","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldManager","type":"address"},{"indexed":true,"internalType":"address","name":"newManager","type":"address"}],"name":"UpdatedVotingPowerManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"AAVE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_UINT256","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STK_AAVE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newManager","type":"address"}],"name":"addPodManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"asset","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"manager","type":"address"}],"name":"blockPodManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bufferRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"convertToShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositToReserve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getCurrentIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDelegates","outputs":[{"internalType":"address","name":"votingPower","type":"address"},{"internalType":"address","name":"proposalPower","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_votingPowerManager","type":"address"},{"internalType":"address","name":"_proposalPowerManager","type":"address"}],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"maxDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"maxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pod","type":"address"},{"internalType":"uint256","name":"addedAmount","type":"uint256"}],"name":"notifyRentedAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"podManagers","outputs":[{"internalType":"bool","name":"rentingAllowed","type":"bool"},{"internalType":"uint248","name":"totalRented","type":"uint248"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"previewDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"previewWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"proposalPowerManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pod","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"pullRentedStkAave","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"recoverERC20","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pod","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"rentStkAave","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reserveAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reserveManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reserveRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"scaledBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAvailable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalRentedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalScaledSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"transferAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newRatio","type":"uint256"}],"name":"updateBufferRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newManager","type":"address"}],"name":"updateProposalPowerManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newManager","type":"address"}],"name":"updateReserveManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newRatio","type":"uint256"}],"name":"updateReserveRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateStkAaveRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newManager","type":"address"}],"name":"updateVotingPowerManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"votingPowerManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"withdrawFromReserve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60c06040526101f4600d553480156200001757600080fd5b5060405162003ef238038062003ef28339810160408190526200003a9162000233565b818160026200004a838262000381565b50600362000059828262000381565b50506004805460ff199081166012179091556001600655600780549091169055506001600160a01b03871615806200009857506001600160a01b038516155b80620000ab57506001600160a01b038416155b80620000be57506001600160a01b038316155b15620000dd57604051639fabe1c160e01b815260040160405180910390fd5b85600003620000ff57604051630e5a744960e41b815260040160405180910390fd5b50506007805462010000600160b01b031916620100006001600160a01b0397881602179055600f93909355601080546001600160a01b03191692851692909217909155821660a052166080526200044d565b80516001600160a01b03811681146200016957600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200019657600080fd5b81516001600160401b0380821115620001b357620001b36200016e565b604051601f8301601f19908116603f01168101908282118183101715620001de57620001de6200016e565b81604052838152602092508683858801011115620001fb57600080fd5b600091505b838210156200021f578582018301518183018401529082019062000200565b600093810190920192909252949350505050565b600080600080600080600060e0888a0312156200024f57600080fd5b6200025a8862000151565b965060208801519550620002716040890162000151565b9450620002816060890162000151565b9350620002916080890162000151565b60a08901519093506001600160401b0380821115620002af57600080fd5b620002bd8b838c0162000184565b935060c08a0151915080821115620002d457600080fd5b50620002e38a828b0162000184565b91505092959891949750929550565b600181811c908216806200030757607f821691505b6020821081036200032857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200037c57600081815260208120601f850160051c81016020861015620003575750805b601f850160051c820191505b81811015620003785782815560010162000363565b5050505b505050565b81516001600160401b038111156200039d576200039d6200016e565b620003b581620003ae8454620002f2565b846200032e565b602080601f831160018114620003ed5760008415620003d45750858301515b600019600386901b1c1916600185901b17855562000378565b600085815260208120601f198616915b828110156200041e57888601518255948401946001909101908401620003fd565b50858210156200043d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a051613a01620004f1600039600081816105c4015281816114e80152612871015260008181610550015281816107ba015281816108ec01528181611523015281816117a701528181611a7d01528181611c7901528181611f61015281816120ad0152818161217501528181612336015281816123b5015281816125060152818161274a0152818161290001528181612a8f0152612d4f0152613a016000f3fe608060405234801561001057600080fd5b50600436106103fc5760003560e01c80638456cb5911610215578063bdf2878d11610125578063d85d7f5b116100b8578063f09a401611610087578063f09a401614610869578063f27ef5c91461087c578063f851a4401461088f578063fd967f47146108a8578063fed371ed146108b157600080fd5b8063d85d7f5b1461084e578063d905777e14610815578063dd62ed3e14610856578063ef8b30f71461043157600080fd5b8063c838ccb6116100f4578063c838ccb6146107ef578063ce96cb7714610815578063cfb982c814610828578063d6d5784f1461083b57600080fd5b8063bdf2878d146107b5578063c415565f146107dc578063c63d75b6146105aa578063c6e6f5921461043157600080fd5b8063a9059cbb116101a8578063b553c08511610177578063b553c08514610717578063b6e1a2f11461072a578063ba0876521461077c578063ba0a3a581461078f578063bb004abc146107a257600080fd5b8063a9059cbb146106de578063b17d718e146106f1578063b3d7f6b914610431578063b460af941461070457600080fd5b80639d8e2177116101e45780639d8e2177146106a05780639e8c708e146106af578063a37f6911146106c2578063a457c2d7146106cb57600080fd5b80638456cb591461066a57806394bf804d1461067257806395d1d05b1461068557806395d89b411461069857600080fd5b806338d52e0f116103105780634cdad506116102a35780636f8b4530116102725780636f8b4530146106165780636fb36bcb1461061e57806370a082311461063157806371526ce51461064457806375829def1461065757600080fd5b80634cdad506146104315780635c975abb146105ef578063659db576146105fa5780636e553f651461060357600080fd5b80633f4ba83a116102df5780633f4ba83a146105a2578063402d267d146105aa57806348ccda3c146105bf5780634b09b72a146105e657600080fd5b806338d52e0f1461054e578063395093511461057457806339c00de91461058757806339c423d11461059a57600080fd5b8063158ef93e11610393578063264f6bb311610362578063264f6bb3146104df57806326782247146104f25780632a9950be1461051d578063313ce5671461053057806333a581d21461054557600080fd5b8063158ef93e1461048057806318160ddd146104925780631da24f3e1461049a57806323b872dd146104cc57600080fd5b80630a28a477116103cf5780630a28a477146104315780630c7d5cd8146104655780630d9005ae1461046e5780630e18b6811461047657600080fd5b806301e1d1141461040157806306fdde031461041c57806307a2d13a14610431578063095ea7b314610442575b600080fd5b6104096108c4565b6040519081526020015b60405180910390f35b610424610970565b604051610413919061362e565b61040961043f366004613661565b90565b610455610450366004613691565b610a02565b6040519015158152602001610413565b610409600f5481565b610409610a19565b61047e610a23565b005b60075461045590610100900460ff1681565b610409610af7565b6104096104a83660046136bb565b6001600160a01b03166000908152600560205260409020546001600160801b031690565b6104556104da3660046136d6565b610b01565b61047e6104ed366004613661565b610bdd565b600854610505906001600160a01b031681565b6040516001600160a01b039091168152602001610413565b61047e61052b3660046136bb565b610c77565b60045460405160ff9091168152602001610413565b61040960001981565b7f0000000000000000000000000000000000000000000000000000000000000000610505565b610455610582366004613691565b610d55565b61047e6105953660046136bb565b610d7c565b61047e610e55565b61047e610e94565b6104096105b83660046136bb565b5060001990565b6105057f000000000000000000000000000000000000000000000000000000000000000081565b610409600e5481565b60075460ff16610455565b61040960095481565b610409610611366004613712565b610ecf565b600054610409565b61047e61062c3660046136bb565b610f8c565b61040961063f3660046136bb565b611066565b61047e610652366004613691565b61109b565b61047e6106653660046136bb565b61124b565b61047e61132a565b610409610680366004613712565b611363565b61047e610693366004613661565b611411565b6104246114a3565b610409670de0b6b3a764000081565b6104556106bd3660046136bb565b6114b2565b610409600d5481565b6104556106d9366004613691565b611671565b6104556106ec366004613691565b6116ba565b6104556106ff366004613661565b6116fe565b61040961071236600461373e565b611827565b61047e610725366004613691565b6118fa565b61075d6107383660046136bb565b600a6020526000908152604090205460ff81169061010090046001600160f81b031682565b6040805192151583526001600160f81b03909116602083015201610413565b61040961078a36600461373e565b611aea565b61047e61079d366004613691565b611bbd565b601054610505906001600160a01b031681565b6105057f000000000000000000000000000000000000000000000000000000000000000081565b6104556107ea366004613712565b611e6e565b600b54600c54604080516001600160a01b03938416815292909116602083015201610413565b6104096108233660046136bb565b611fea565b61047e6108363660046136bb565b611ff5565b600b54610505906001600160a01b031681565b610409612153565b61040961086436600461377a565b612248565b61047e61087736600461377a565b612273565b61047e61088a3660046136bb565b61244e565b600754610505906201000090046001600160a01b031681565b61040961271081565b600c54610505906001600160a01b031681565b600e546009546040516370a0823160e01b815230600482015260009291906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015610933573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095791906137a4565b61096191906137d3565b61096b91906137e6565b905090565b60606002805461097f906137f9565b80601f01602080910402602001604051908101604052809291908181526020018280546109ab906137f9565b80156109f85780601f106109cd576101008083540402835291602001916109f8565b820191906000526020600020905b8154815290600101906020018083116109db57829003601f168201915b5050505050905090565b6000610a0f3384846125ac565b5060015b92915050565b600061096b612648565b6008546001600160a01b03163314610a4e57604051630ac6491560e01b815260040160405180910390fd5b6008805460078054620100006001600160a01b0380851682810262010000600160b01b03198516179094556001600160a01b03199094169094556040519193900490911690829082907ff8ccb027dfcd135e000e9d45e6cc2d662578a8825d4c45b5e32e0adf67e79ec690600090a36040516000906001600160a01b038416907fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a9908390a35050565b600061096b6108c4565b6001600160a01b038316600090815260016020908152604080832033845290915281205482811015610b46576040516364b3d8c760e01b815260040160405180910390fd5b6000198114610b8a576001600160a01b038516600090815260016020908152604080832033808552925290912054610b8a918791610b859087906137e6565b6125ac565b610b95858585612678565b836001600160a01b0316856001600160a01b03166000805160206139ac83398151915285604051610bc891815260200190565b60405180910390a360019150505b9392505050565b6007546201000090046001600160a01b03163314610c0e5760405163036c8cf960e11b815260040160405180910390fd5b6105dc811115610c3157604051630309cb8760e51b815260040160405180910390fd5b600d80549082905560408051828152602081018490527ff4eb55c9d5784e11db6a6ec12075c6539bbf1f33dd6e5167d622dd409570688d91015b60405180910390a15050565b6007546201000090046001600160a01b03163314610ca85760405163036c8cf960e11b815260040160405180910390fd5b6001600160a01b038116610ccf57604051639fabe1c160e01b815260040160405180910390fd5b6001600160a01b0381166000908152600a602052604090205460ff1615610d09576040516351b6234d60e11b815260040160405180910390fd5b6001600160a01b0381166000818152600a6020526040808220805460ff19166001179055517f24a580edd7d72eaf169d7530d023d8e608352e77e0e132cff8c2a8955b00bb279190a250565b600033610d72818585610d688383612248565b610b8591906137d3565b5060019392505050565b6007546201000090046001600160a01b03163314610dad5760405163036c8cf960e11b815260040160405180910390fd5b6001600160a01b038116610dd457604051639fabe1c160e01b815260040160405180910390fd5b6010546001600160a01b0390811690821603610e035760405163367558c360e01b815260040160405180910390fd5b601080546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f79b97624b2eef26c75b54eb94adf1e51d19018df8d5b05e3fde9dfbef209040590600090a35050565b600260065403610e805760405162461bcd60e51b8152600401610e7790613833565b60405180910390fd5b6002600655610e8d612735565b6001600655565b6007546201000090046001600160a01b03163314610ec55760405163036c8cf960e11b815260040160405180910390fd5b610ecd61298b565b565b600754600090610100900460ff16610efa576040516321c4e35760e21b815260040160405180910390fd5b600260065403610f1c5760405162461bcd60e51b8152600401610e7790613833565b6002600655610f296129dd565b610f34838333612a23565b60408051838152602081018390529295509092506001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d791015b60405180910390a3600160065592915050565b6007546201000090046001600160a01b03163314610fbd5760405163036c8cf960e11b815260040160405180910390fd5b6001600160a01b038116610fe457604051639fabe1c160e01b815260040160405180910390fd5b6001600160a01b0381166000908152600a602052604090205460ff1661101d576040516353182fc160e11b815260040160405180910390fd5b6001600160a01b0381166000818152600a6020526040808220805460ff19169055517fee27a3e7a8b63b60512a9b8b1c49bdf64c712021a5d4459beddfb87fb72f55819190a250565b6000610a13611073612648565b6001600160a01b0384166000908152600560205260409020546001600160801b031690612acf565b6002600654036110bd5760405162461bcd60e51b8152600401610e7790613833565b6002600655336000818152600a602052604081205461010090046001600160f81b031690036110ff576040516370bd2a8560e11b815260040160405180910390fd5b6001600160a01b03831661112657604051639fabe1c160e01b815260040160405180910390fd5b8160000361114757604051630e5a744960e41b815260040160405180910390fd5b61115082612b11565b6001600160a01b0382166000908152600a60205260409020805460019061118690849061010090046001600160f81b031661386a565b92506101000a8154816001600160f81b0302191690836001600160f81b0316021790555081600960008282546111bc91906137d3565b9091555050600f54612710906111d29084613891565b6111dc91906138b0565b600e60008282546111ed91906137d3565b92505081905550826001600160a01b0316816001600160a01b03167f8ac0d63df3c915ef42ced3274ab222a7932776d6cc50de74d25cd5a225f420148460405161123991815260200190565b60405180910390a35050600160065550565b6007546201000090046001600160a01b0316331461127c5760405163036c8cf960e11b815260040160405180910390fd5b6001600160a01b0381166112a357604051639fabe1c160e01b815260040160405180910390fd5b6007546001600160a01b03620100009091048116908216036112d8576040516335803f0160e01b815260040160405180910390fd5b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a990600090a35050565b6007546201000090046001600160a01b0316331461135b5760405163036c8cf960e11b815260040160405180910390fd5b610ecd612b3f565b600754600090610100900460ff1661138e576040516321c4e35760e21b815260040160405180910390fd5b6002600654036113b05760405162461bcd60e51b8152600401610e7790613833565b60026006556113bd6129dd565b6113c8838333612a23565b60408051838152602081018390529195509192506001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d79101610f79565b6007546201000090046001600160a01b031633146114425760405163036c8cf960e11b815260040160405180910390fd5b6105dc81111561146557604051630309cb8760e51b815260040160405180910390fd5b600f80549082905560408051828152602081018490527fd56cfcea46fe9dc52c77ef7c03b5481be192c845dcad56ac266e399cd29b1dab9101610c6b565b60606003805461097f906137f9565b6007546000906201000090046001600160a01b031633146114e65760405163036c8cf960e11b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316148061155757507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316145b15611575576040516380eb2a0160e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa1580156115bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e091906137a4565b90508060000361160357604051630e5a744960e41b815260040160405180910390fd5b600754611623906001600160a01b03858116916201000090041683612b7c565b826001600160a01b03167f4590b594be6fdef6bd5e18792a2494ddf2156b618c7bbe48d13a92831208af058260405161165e91815260200190565b60405180910390a260019150505b919050565b6000338161167f8286612248565b9050838110156116a2576040516389532b7d60e01b815260040160405180910390fd5b6116af82868684036125ac565b506001949350505050565b60006116c7338484612678565b6040518281526001600160a01b0384169033906000805160206139ac8339815191529060200160405180910390a350600192915050565b60006002600654036117225760405162461bcd60e51b8152600401610e7790613833565b60026006556007546201000090046001600160a01b0316331480159061175357506010546001600160a01b03163314155b156117715760405163036c8cf960e11b815260040160405180910390fd5b8160000361179257604051630e5a744960e41b815260040160405180910390fd5b61179a612735565b6117cf6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333085612be4565b81600e60008282546117e191906137d3565b909155505060405182815233907f418979cce08cdd6e1bb0e09c0b1df658cf18921d5979efb980f189b35907bb2f9060200160405180910390a250600180600655919050565b600754600090610100900460ff16611852576040516321c4e35760e21b815260040160405180910390fd5b6002600654036118745760405162461bcd60e51b8152600401610e7790613833565b600260065560008061188886858733612c1c565b91509150836001600160a01b0316856001600160a01b0316336001600160a01b03167ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db85856040516118e4929190918252602082015260400190565b60405180910390a4600160065595945050505050565b60026006540361191c5760405162461bcd60e51b8152600401610e7790613833565b6002600655336000818152600a602052604081205461010090046001600160f81b0316900361195e576040516370bd2a8560e11b815260040160405180910390fd5b6001600160a01b03831661198557604051639fabe1c160e01b815260040160405180910390fd5b816000036119a657604051630e5a744960e41b815260040160405180910390fd5b6001600160a01b0381166000908152600a602052604090205461010090046001600160f81b03168211156119ed576040516364ddcf3760e01b815260040160405180910390fd5b6119f5612735565b6119fe82612b11565b6001600160a01b0382166000908152600a602052604090208054600190611a3490849061010090046001600160f81b03166138d2565b92506101000a8154816001600160f81b0302191690836001600160f81b031602179055508160096000828254611a6a91906137e6565b90915550611aa590506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016843085612be4565b826001600160a01b0316816001600160a01b03167f8f3c36759a69d5bda5c0381c2c1137caea3a3e9547d86ec860d019f3591dd2468460405161123991815260200190565b600754600090610100900460ff16611b15576040516321c4e35760e21b815260040160405180910390fd5b600260065403611b375760405162461bcd60e51b8152600401610e7790613833565b6002600655600080611b4b86858733612c1c565b91509150836001600160a01b0316856001600160a01b0316336001600160a01b03167ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db8585604051611ba7929190918252602082015260400190565b60405180910390a4506001600655949350505050565b600260065403611bdf5760405162461bcd60e51b8152600401610e7790613833565b6002600655336000818152600a602052604090205460ff16611c1457604051630bf6175d60e11b815260040160405180910390fd5b6001600160a01b038316611c3b57604051639fabe1c160e01b815260040160405180910390fd5b81600003611c5c57604051630e5a744960e41b815260040160405180910390fd5b611c64612735565b6040516370a0823160e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000906000906001600160a01b038316906370a0823190602401602060405180830381865afa158015611ccd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cf191906137a4565b905080600e541015611d0f57600e54611d0a90826137e6565b611d12565b60005b90506000612710600d54611d246108c4565b611d2e9190613891565b611d3891906138b0565b905080821015611d5b576040516309262c7f60e41b815260040160405180910390fd5b611d6581836137e6565b851115611d85576040516326f1bf9360e01b815260040160405180910390fd5b611d8e85612b11565b6001600160a01b0385166000908152600a602052604090208054600190611dc490849061010090046001600160f81b031661386a565b92506101000a8154816001600160f81b0302191690836001600160f81b031602179055508460096000828254611dfa91906137d3565b90915550611e1490506001600160a01b0384168787612b7c565b856001600160a01b0316846001600160a01b03167f99602732910020e2e51a839f33ced64c6b36b6b64a2c225e52cdd8ef6c07d9f987604051611e5991815260200190565b60405180910390a35050600160065550505050565b6000600260065403611e925760405162461bcd60e51b8152600401610e7790613833565b60026006556007546201000090046001600160a01b03163314801590611ec357506010546001600160a01b03163314155b15611ee15760405163036c8cf960e11b815260040160405180910390fd5b82600003611f0257604051630e5a744960e41b815260040160405180910390fd5b6001600160a01b038216611f2957604051639fabe1c160e01b815260040160405180910390fd5b600e54831115611f4c57604051634cc7b59d60e01b815260040160405180910390fd5b611f54612735565b611f886001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168385612b7c565b82600e6000828254611f9a91906137e6565b90915550506040518381526001600160a01b038316907f0529afc4538720fe0b3eadc40486369ab962002d72fead1387b300c66073e7bf9060200160405180910390a25060018060065592915050565b6000610a1382611066565b6007546201000090046001600160a01b031633146120265760405163036c8cf960e11b815260040160405180910390fd5b6001600160a01b03811661204d57604051639fabe1c160e01b815260040160405180910390fd5b600b546001600160a01b039081169082160361207c5760405163367558c360e01b815260040160405180910390fd5b600b80546001600160a01b038381166001600160a01b0319831617909255604051633724df8760e21b8152908216917f0000000000000000000000000000000000000000000000000000000000000000169063dc937e1c906120e59085906000906004016138f2565b600060405180830381600087803b1580156120ff57600080fd5b505af1158015612113573d6000803e3d6000fd5b50506040516001600160a01b038086169350841691507f1703370ea1b3aaecb46974b10cd9534323f8b62d4b5c858e78c34ac64d4e329490600090a35050565b6040516370a0823160e01b815230600482015260009081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156121bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121e091906137a4565b905080600e5410156121fe57600e546121f990826137e6565b612201565b60005b90506000612710600d546122136108c4565b61221d9190613891565b61222791906138b0565b9050808211612237576000612241565b61224181836137e6565b9250505090565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6007546201000090046001600160a01b031633146122a45760405163036c8cf960e11b815260040160405180910390fd5b600754610100900460ff16156122cc5760405162dc149f60e41b815260040160405180910390fd5b6007805461ff001916610100179055600b80546001600160a01b038085166001600160a01b031992831617909255600c80549284169290911691909117905561231d66038d7ea4c680003380612a23565b5050604051633724df8760e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063dc937e1c9061236e9085906000906004016138f2565b600060405180830381600087803b15801561238857600080fd5b505af115801561239c573d6000803e3d6000fd5b5050604051633724df8760e21b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016925063dc937e1c91506123ef9084906001906004016138f2565b600060405180830381600087803b15801561240957600080fd5b505af115801561241d573d6000803e3d6000fd5b50506040517f5daa87a0e9463431830481fd4b6e3403442dfb9a12b9c07597e9f61d50b633c8925060009150a15050565b6007546201000090046001600160a01b0316331461247f5760405163036c8cf960e11b815260040160405180910390fd5b6001600160a01b0381166124a657604051639fabe1c160e01b815260040160405180910390fd5b600c546001600160a01b03908116908216036124d55760405163367558c360e01b815260040160405180910390fd5b600c80546001600160a01b038381166001600160a01b0319831617909255604051633724df8760e21b8152908216917f0000000000000000000000000000000000000000000000000000000000000000169063dc937e1c9061253e9085906001906004016138f2565b600060405180830381600087803b15801561255857600080fd5b505af115801561256c573d6000803e3d6000fd5b50506040516001600160a01b038086169350841691507f97fb01cd0e4b307e0835da37ae485767ec7107d154a4abfb2b58f3730e6f4cef90600090a35050565b6001600160a01b03831615806125c957506001600160a01b038216155b156125e757604051632b65113b60e01b815260040160405180910390fd5b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6000805460000361266457506b033b2e3c9fd0803ce800000090565b61096b6000546126726108c4565b90612e3b565b6001600160a01b038316158061269557506001600160a01b038216155b156126b35760405163b53aab2360e01b815260040160405180910390fd5b816001600160a01b0316836001600160a01b0316036126e55760405163b3e918cb60e01b815260040160405180910390fd5b806000036127065760405163b3fcf27960e01b815260040160405180910390fd5b600061272261271d612716612648565b8490612e3b565b612e74565b905061272f848483612e9e565b50505050565b6040516346df7f7160e11b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000906000906001600160a01b03831690638dbefee290602401602060405180830381865afa15801561279e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127c291906137a4565b9050801561285c576040516309a99b4f60e41b8152306004820152602481018290526001600160a01b03831690639a99b4f090604401600060405180830381600087803b15801561281257600080fd5b505af1158015612826573d6000803e3d6000fd5b50505050612710600f548261283b9190613891565b61284591906138b0565b600e600082825461285691906137d3565b90915550505b6040516370a0823160e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000906000906001600160a01b038316906370a0823190602401602060405180830381865afa1580156128c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128e991906137a4565b9050801561272f576129256001600160a01b0383167f000000000000000000000000000000000000000000000000000000000000000083612f57565b6040516356e4bb9760e11b8152306004820152602481018290526001600160a01b0385169063adc9772e90604401600060405180830381600087803b15801561296d57600080fd5b505af1158015612981573d6000803e3d6000fd5b5050505050505050565b612993613009565b6007805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60075460ff1615610ecd5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610e77565b6000806001600160a01b038416612a4d57604051639fabe1c160e01b815260040160405180910390fd5b84600003612a6e57604051630e5a744960e41b815260040160405180910390fd5b612a76612735565b6000612a80612648565b9050612ab76001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016853089612be4565b6000612ac4868884613052565b969795505050505050565b6000816b019d971e4fe8401e7400000019048311820215612aef57600080fd5b506b033b2e3c9fd0803ce800000091026b019d971e4fe8401e74000000010490565b60006001600160f81b03821115612b3b57604051635a7eea2760e11b815260040160405180910390fd5b5090565b612b476129dd565b6007805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586129c03390565b6040516001600160a01b038316602482015260448101829052612bdf90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526131bd565b505050565b6040516001600160a01b038085166024830152831660448201526064810182905261272f9085906323b872dd60e01b90608401612ba8565b6000806001600160a01b0384161580612c3c57506001600160a01b038516155b15612c5a57604051639fabe1c160e01b815260040160405180910390fd5b85600003612c7b57604051630e5a744960e41b815260040160405180910390fd5b612c83612735565b60006000198703612c9e57612c9786611066565b9650600190505b836001600160a01b0316866001600160a01b031614612d3a576001600160a01b0380871660009081526001602090815260408083209388168352929052205487811015612cfe576040516364b3d8c760e01b815260040160405180910390fd5b6000198114612d3857612d1188826137e6565b6001600160a01b038089166000908152600160209081526040808320938a16835292905220555b505b6040516370a0823160e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000906000906001600160a01b038316906370a0823190602401602060405180830381865afa158015612da3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dc791906137a4565b905080600e541015612de557600e54612de090826137e6565b612de8565b60005b905080891115612e0b576040516326f1bf9360e01b815260040160405180910390fd5b6000612e18898b8661328f565b9050612e2e6001600160a01b038416898c612b7c565b9899975050505050505050565b600281046b033b2e3c9fd0803ce80000008119048311158202612e5d57600080fd5b6b033b2e3c9fd0803ce80000009092029091010490565b60006001600160801b03821115612b3b57604051638ac92bf960e01b815260040160405180910390fd5b6001600160a01b0383166000908152600560205260409020546001600160801b039081169082161115612ee45760405163a50f989960e01b815260040160405180910390fd5b612ef88383836001600160801b0316613459565b6001600160a01b0392831660009081526005602052604080822080546001600160801b0380821686900381166fffffffffffffffffffffffffffffffff1992831617909255949095168252902080548085169092019093169116179055565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015612fa8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fcc91906137a4565b612fd691906137d3565b6040516001600160a01b03851660248201526044810182905290915061272f90859063095ea7b360e01b90606401612ba8565b60075460ff16610ecd5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610e77565b60008061305f8484612e3b565b9050806000036130825760405163b3fcf27960e01b815260040160405180910390fd5b61308e60008683613459565b61309783612e74565b6001600160a01b038616600090815260056020526040812080546001600160801b03938416600160801b02931692909217909155805482919081906130dd9084906137d3565b909155506130ec905081612e74565b6001600160a01b0386166000908152600560205260408120805490919061311d9084906001600160801b031661392d565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555060408051828152602081018590526001600160a01b038716917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a26040518481526001600160a01b038616906000906000805160206139ac8339815191529060200160405180910390a350919392505050565b6000613212826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166134899092919063ffffffff16565b805190915015612bdf5780806020019051810190613230919061394d565b612bdf5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610e77565b60008061329a612648565b6001600160a01b0386166000908152600560205260408120549192506001600160801b0390911690846132d6576132d18684612e3b565b6132d8565b815b9050806000036132fb5760405163b3fcf27960e01b815260040160405180910390fd5b8181111561331c5760405163a50f989960e01b815260040160405180910390fd5b61332887600083613459565b61333183612e74565b6001600160a01b038816600090815260056020526040812080546001600160801b03938416600160801b02931692909217909155805482919081906133779084906137e6565b90915550613386905081612e74565b6001600160a01b038816600090815260056020526040812080549091906133b79084906001600160801b031661396f565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555060408051828152602081018590526001600160a01b038916917f49995e5dd6158cf69ad3e9777c46755a1a826a446c6416992167462dad033b2a910160405180910390a26040518681526000906001600160a01b038916906000805160206139ac8339815191529060200160405180910390a3509395945050505050565b600754610100900460ff16613481576040516321c4e35760e21b815260040160405180910390fd5b612bdf6129dd565b606061349884846000856134a0565b949350505050565b6060824710156135015760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610e77565b6001600160a01b0385163b6135585760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610e77565b600080866001600160a01b03168587604051613574919061398f565b60006040518083038185875af1925050503d80600081146135b1576040519150601f19603f3d011682016040523d82523d6000602084013e6135b6565b606091505b50915091506135c68282866135d1565b979650505050505050565b606083156135e0575081610bd6565b8251156135f05782518084602001fd5b8160405162461bcd60e51b8152600401610e77919061362e565b60005b8381101561362557818101518382015260200161360d565b50506000910152565b602081526000825180602084015261364d81604085016020870161360a565b601f01601f19169190910160400192915050565b60006020828403121561367357600080fd5b5035919050565b80356001600160a01b038116811461166c57600080fd5b600080604083850312156136a457600080fd5b6136ad8361367a565b946020939093013593505050565b6000602082840312156136cd57600080fd5b610bd68261367a565b6000806000606084860312156136eb57600080fd5b6136f48461367a565b92506137026020850161367a565b9150604084013590509250925092565b6000806040838503121561372557600080fd5b823591506137356020840161367a565b90509250929050565b60008060006060848603121561375357600080fd5b833592506137636020850161367a565b91506137716040850161367a565b90509250925092565b6000806040838503121561378d57600080fd5b6137968361367a565b91506137356020840161367a565b6000602082840312156137b657600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610a1357610a136137bd565b81810381811115610a1357610a136137bd565b600181811c9082168061380d57607f821691505b60208210810361382d57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6001600160f81b0381811683821601908082111561388a5761388a6137bd565b5092915050565b60008160001904831182151516156138ab576138ab6137bd565b500290565b6000826138cd57634e487b7160e01b600052601260045260246000fd5b500490565b6001600160f81b0382811682821603908082111561388a5761388a6137bd565b6001600160a01b0383168152604081016002831061392057634e487b7160e01b600052602160045260246000fd5b8260208301529392505050565b6001600160801b0381811683821601908082111561388a5761388a6137bd565b60006020828403121561395f57600080fd5b81518015158114610bd657600080fd5b6001600160801b0382811682821603908082111561388a5761388a6137bd565b600082516139a181846020870161360a565b919091019291505056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122044f2632f32f061f871ee940d3dc81e0a314dab2e1f93c36e5c234813b9d9f70a64736f6c63430008100033000000000000000000000000bfd7a3dafed7c2d48b3374f6c4df946ba37395e500000000000000000000000000000000000000000000000000000000000001f4000000000000000000000000bfd7a3dafed7c2d48b3374f6c4df946ba37395e50000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae90000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f500000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000001044756c6c6168616e2073746b416176650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086473746b41415645000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103fc5760003560e01c80638456cb5911610215578063bdf2878d11610125578063d85d7f5b116100b8578063f09a401611610087578063f09a401614610869578063f27ef5c91461087c578063f851a4401461088f578063fd967f47146108a8578063fed371ed146108b157600080fd5b8063d85d7f5b1461084e578063d905777e14610815578063dd62ed3e14610856578063ef8b30f71461043157600080fd5b8063c838ccb6116100f4578063c838ccb6146107ef578063ce96cb7714610815578063cfb982c814610828578063d6d5784f1461083b57600080fd5b8063bdf2878d146107b5578063c415565f146107dc578063c63d75b6146105aa578063c6e6f5921461043157600080fd5b8063a9059cbb116101a8578063b553c08511610177578063b553c08514610717578063b6e1a2f11461072a578063ba0876521461077c578063ba0a3a581461078f578063bb004abc146107a257600080fd5b8063a9059cbb146106de578063b17d718e146106f1578063b3d7f6b914610431578063b460af941461070457600080fd5b80639d8e2177116101e45780639d8e2177146106a05780639e8c708e146106af578063a37f6911146106c2578063a457c2d7146106cb57600080fd5b80638456cb591461066a57806394bf804d1461067257806395d1d05b1461068557806395d89b411461069857600080fd5b806338d52e0f116103105780634cdad506116102a35780636f8b4530116102725780636f8b4530146106165780636fb36bcb1461061e57806370a082311461063157806371526ce51461064457806375829def1461065757600080fd5b80634cdad506146104315780635c975abb146105ef578063659db576146105fa5780636e553f651461060357600080fd5b80633f4ba83a116102df5780633f4ba83a146105a2578063402d267d146105aa57806348ccda3c146105bf5780634b09b72a146105e657600080fd5b806338d52e0f1461054e578063395093511461057457806339c00de91461058757806339c423d11461059a57600080fd5b8063158ef93e11610393578063264f6bb311610362578063264f6bb3146104df57806326782247146104f25780632a9950be1461051d578063313ce5671461053057806333a581d21461054557600080fd5b8063158ef93e1461048057806318160ddd146104925780631da24f3e1461049a57806323b872dd146104cc57600080fd5b80630a28a477116103cf5780630a28a477146104315780630c7d5cd8146104655780630d9005ae1461046e5780630e18b6811461047657600080fd5b806301e1d1141461040157806306fdde031461041c57806307a2d13a14610431578063095ea7b314610442575b600080fd5b6104096108c4565b6040519081526020015b60405180910390f35b610424610970565b604051610413919061362e565b61040961043f366004613661565b90565b610455610450366004613691565b610a02565b6040519015158152602001610413565b610409600f5481565b610409610a19565b61047e610a23565b005b60075461045590610100900460ff1681565b610409610af7565b6104096104a83660046136bb565b6001600160a01b03166000908152600560205260409020546001600160801b031690565b6104556104da3660046136d6565b610b01565b61047e6104ed366004613661565b610bdd565b600854610505906001600160a01b031681565b6040516001600160a01b039091168152602001610413565b61047e61052b3660046136bb565b610c77565b60045460405160ff9091168152602001610413565b61040960001981565b7f0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f5610505565b610455610582366004613691565b610d55565b61047e6105953660046136bb565b610d7c565b61047e610e55565b61047e610e94565b6104096105b83660046136bb565b5060001990565b6105057f0000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae981565b610409600e5481565b60075460ff16610455565b61040960095481565b610409610611366004613712565b610ecf565b600054610409565b61047e61062c3660046136bb565b610f8c565b61040961063f3660046136bb565b611066565b61047e610652366004613691565b61109b565b61047e6106653660046136bb565b61124b565b61047e61132a565b610409610680366004613712565b611363565b61047e610693366004613661565b611411565b6104246114a3565b610409670de0b6b3a764000081565b6104556106bd3660046136bb565b6114b2565b610409600d5481565b6104556106d9366004613691565b611671565b6104556106ec366004613691565b6116ba565b6104556106ff366004613661565b6116fe565b61040961071236600461373e565b611827565b61047e610725366004613691565b6118fa565b61075d6107383660046136bb565b600a6020526000908152604090205460ff81169061010090046001600160f81b031682565b6040805192151583526001600160f81b03909116602083015201610413565b61040961078a36600461373e565b611aea565b61047e61079d366004613691565b611bbd565b601054610505906001600160a01b031681565b6105057f0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f581565b6104556107ea366004613712565b611e6e565b600b54600c54604080516001600160a01b03938416815292909116602083015201610413565b6104096108233660046136bb565b611fea565b61047e6108363660046136bb565b611ff5565b600b54610505906001600160a01b031681565b610409612153565b61040961086436600461377a565b612248565b61047e61087736600461377a565b612273565b61047e61088a3660046136bb565b61244e565b600754610505906201000090046001600160a01b031681565b61040961271081565b600c54610505906001600160a01b031681565b600e546009546040516370a0823160e01b815230600482015260009291906001600160a01b037f0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f516906370a0823190602401602060405180830381865afa158015610933573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095791906137a4565b61096191906137d3565b61096b91906137e6565b905090565b60606002805461097f906137f9565b80601f01602080910402602001604051908101604052809291908181526020018280546109ab906137f9565b80156109f85780601f106109cd576101008083540402835291602001916109f8565b820191906000526020600020905b8154815290600101906020018083116109db57829003601f168201915b5050505050905090565b6000610a0f3384846125ac565b5060015b92915050565b600061096b612648565b6008546001600160a01b03163314610a4e57604051630ac6491560e01b815260040160405180910390fd5b6008805460078054620100006001600160a01b0380851682810262010000600160b01b03198516179094556001600160a01b03199094169094556040519193900490911690829082907ff8ccb027dfcd135e000e9d45e6cc2d662578a8825d4c45b5e32e0adf67e79ec690600090a36040516000906001600160a01b038416907fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a9908390a35050565b600061096b6108c4565b6001600160a01b038316600090815260016020908152604080832033845290915281205482811015610b46576040516364b3d8c760e01b815260040160405180910390fd5b6000198114610b8a576001600160a01b038516600090815260016020908152604080832033808552925290912054610b8a918791610b859087906137e6565b6125ac565b610b95858585612678565b836001600160a01b0316856001600160a01b03166000805160206139ac83398151915285604051610bc891815260200190565b60405180910390a360019150505b9392505050565b6007546201000090046001600160a01b03163314610c0e5760405163036c8cf960e11b815260040160405180910390fd5b6105dc811115610c3157604051630309cb8760e51b815260040160405180910390fd5b600d80549082905560408051828152602081018490527ff4eb55c9d5784e11db6a6ec12075c6539bbf1f33dd6e5167d622dd409570688d91015b60405180910390a15050565b6007546201000090046001600160a01b03163314610ca85760405163036c8cf960e11b815260040160405180910390fd5b6001600160a01b038116610ccf57604051639fabe1c160e01b815260040160405180910390fd5b6001600160a01b0381166000908152600a602052604090205460ff1615610d09576040516351b6234d60e11b815260040160405180910390fd5b6001600160a01b0381166000818152600a6020526040808220805460ff19166001179055517f24a580edd7d72eaf169d7530d023d8e608352e77e0e132cff8c2a8955b00bb279190a250565b600033610d72818585610d688383612248565b610b8591906137d3565b5060019392505050565b6007546201000090046001600160a01b03163314610dad5760405163036c8cf960e11b815260040160405180910390fd5b6001600160a01b038116610dd457604051639fabe1c160e01b815260040160405180910390fd5b6010546001600160a01b0390811690821603610e035760405163367558c360e01b815260040160405180910390fd5b601080546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f79b97624b2eef26c75b54eb94adf1e51d19018df8d5b05e3fde9dfbef209040590600090a35050565b600260065403610e805760405162461bcd60e51b8152600401610e7790613833565b60405180910390fd5b6002600655610e8d612735565b6001600655565b6007546201000090046001600160a01b03163314610ec55760405163036c8cf960e11b815260040160405180910390fd5b610ecd61298b565b565b600754600090610100900460ff16610efa576040516321c4e35760e21b815260040160405180910390fd5b600260065403610f1c5760405162461bcd60e51b8152600401610e7790613833565b6002600655610f296129dd565b610f34838333612a23565b60408051838152602081018390529295509092506001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d791015b60405180910390a3600160065592915050565b6007546201000090046001600160a01b03163314610fbd5760405163036c8cf960e11b815260040160405180910390fd5b6001600160a01b038116610fe457604051639fabe1c160e01b815260040160405180910390fd5b6001600160a01b0381166000908152600a602052604090205460ff1661101d576040516353182fc160e11b815260040160405180910390fd5b6001600160a01b0381166000818152600a6020526040808220805460ff19169055517fee27a3e7a8b63b60512a9b8b1c49bdf64c712021a5d4459beddfb87fb72f55819190a250565b6000610a13611073612648565b6001600160a01b0384166000908152600560205260409020546001600160801b031690612acf565b6002600654036110bd5760405162461bcd60e51b8152600401610e7790613833565b6002600655336000818152600a602052604081205461010090046001600160f81b031690036110ff576040516370bd2a8560e11b815260040160405180910390fd5b6001600160a01b03831661112657604051639fabe1c160e01b815260040160405180910390fd5b8160000361114757604051630e5a744960e41b815260040160405180910390fd5b61115082612b11565b6001600160a01b0382166000908152600a60205260409020805460019061118690849061010090046001600160f81b031661386a565b92506101000a8154816001600160f81b0302191690836001600160f81b0316021790555081600960008282546111bc91906137d3565b9091555050600f54612710906111d29084613891565b6111dc91906138b0565b600e60008282546111ed91906137d3565b92505081905550826001600160a01b0316816001600160a01b03167f8ac0d63df3c915ef42ced3274ab222a7932776d6cc50de74d25cd5a225f420148460405161123991815260200190565b60405180910390a35050600160065550565b6007546201000090046001600160a01b0316331461127c5760405163036c8cf960e11b815260040160405180910390fd5b6001600160a01b0381166112a357604051639fabe1c160e01b815260040160405180910390fd5b6007546001600160a01b03620100009091048116908216036112d8576040516335803f0160e01b815260040160405180910390fd5b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a990600090a35050565b6007546201000090046001600160a01b0316331461135b5760405163036c8cf960e11b815260040160405180910390fd5b610ecd612b3f565b600754600090610100900460ff1661138e576040516321c4e35760e21b815260040160405180910390fd5b6002600654036113b05760405162461bcd60e51b8152600401610e7790613833565b60026006556113bd6129dd565b6113c8838333612a23565b60408051838152602081018390529195509192506001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d79101610f79565b6007546201000090046001600160a01b031633146114425760405163036c8cf960e11b815260040160405180910390fd5b6105dc81111561146557604051630309cb8760e51b815260040160405180910390fd5b600f80549082905560408051828152602081018490527fd56cfcea46fe9dc52c77ef7c03b5481be192c845dcad56ac266e399cd29b1dab9101610c6b565b60606003805461097f906137f9565b6007546000906201000090046001600160a01b031633146114e65760405163036c8cf960e11b815260040160405180910390fd5b7f0000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae96001600160a01b0316826001600160a01b0316148061155757507f0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f56001600160a01b0316826001600160a01b0316145b15611575576040516380eb2a0160e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa1580156115bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e091906137a4565b90508060000361160357604051630e5a744960e41b815260040160405180910390fd5b600754611623906001600160a01b03858116916201000090041683612b7c565b826001600160a01b03167f4590b594be6fdef6bd5e18792a2494ddf2156b618c7bbe48d13a92831208af058260405161165e91815260200190565b60405180910390a260019150505b919050565b6000338161167f8286612248565b9050838110156116a2576040516389532b7d60e01b815260040160405180910390fd5b6116af82868684036125ac565b506001949350505050565b60006116c7338484612678565b6040518281526001600160a01b0384169033906000805160206139ac8339815191529060200160405180910390a350600192915050565b60006002600654036117225760405162461bcd60e51b8152600401610e7790613833565b60026006556007546201000090046001600160a01b0316331480159061175357506010546001600160a01b03163314155b156117715760405163036c8cf960e11b815260040160405180910390fd5b8160000361179257604051630e5a744960e41b815260040160405180910390fd5b61179a612735565b6117cf6001600160a01b037f0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f516333085612be4565b81600e60008282546117e191906137d3565b909155505060405182815233907f418979cce08cdd6e1bb0e09c0b1df658cf18921d5979efb980f189b35907bb2f9060200160405180910390a250600180600655919050565b600754600090610100900460ff16611852576040516321c4e35760e21b815260040160405180910390fd5b6002600654036118745760405162461bcd60e51b8152600401610e7790613833565b600260065560008061188886858733612c1c565b91509150836001600160a01b0316856001600160a01b0316336001600160a01b03167ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db85856040516118e4929190918252602082015260400190565b60405180910390a4600160065595945050505050565b60026006540361191c5760405162461bcd60e51b8152600401610e7790613833565b6002600655336000818152600a602052604081205461010090046001600160f81b0316900361195e576040516370bd2a8560e11b815260040160405180910390fd5b6001600160a01b03831661198557604051639fabe1c160e01b815260040160405180910390fd5b816000036119a657604051630e5a744960e41b815260040160405180910390fd5b6001600160a01b0381166000908152600a602052604090205461010090046001600160f81b03168211156119ed576040516364ddcf3760e01b815260040160405180910390fd5b6119f5612735565b6119fe82612b11565b6001600160a01b0382166000908152600a602052604090208054600190611a3490849061010090046001600160f81b03166138d2565b92506101000a8154816001600160f81b0302191690836001600160f81b031602179055508160096000828254611a6a91906137e6565b90915550611aa590506001600160a01b037f0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f516843085612be4565b826001600160a01b0316816001600160a01b03167f8f3c36759a69d5bda5c0381c2c1137caea3a3e9547d86ec860d019f3591dd2468460405161123991815260200190565b600754600090610100900460ff16611b15576040516321c4e35760e21b815260040160405180910390fd5b600260065403611b375760405162461bcd60e51b8152600401610e7790613833565b6002600655600080611b4b86858733612c1c565b91509150836001600160a01b0316856001600160a01b0316336001600160a01b03167ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db8585604051611ba7929190918252602082015260400190565b60405180910390a4506001600655949350505050565b600260065403611bdf5760405162461bcd60e51b8152600401610e7790613833565b6002600655336000818152600a602052604090205460ff16611c1457604051630bf6175d60e11b815260040160405180910390fd5b6001600160a01b038316611c3b57604051639fabe1c160e01b815260040160405180910390fd5b81600003611c5c57604051630e5a744960e41b815260040160405180910390fd5b611c64612735565b6040516370a0823160e01b81523060048201527f0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f5906000906001600160a01b038316906370a0823190602401602060405180830381865afa158015611ccd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cf191906137a4565b905080600e541015611d0f57600e54611d0a90826137e6565b611d12565b60005b90506000612710600d54611d246108c4565b611d2e9190613891565b611d3891906138b0565b905080821015611d5b576040516309262c7f60e41b815260040160405180910390fd5b611d6581836137e6565b851115611d85576040516326f1bf9360e01b815260040160405180910390fd5b611d8e85612b11565b6001600160a01b0385166000908152600a602052604090208054600190611dc490849061010090046001600160f81b031661386a565b92506101000a8154816001600160f81b0302191690836001600160f81b031602179055508460096000828254611dfa91906137d3565b90915550611e1490506001600160a01b0384168787612b7c565b856001600160a01b0316846001600160a01b03167f99602732910020e2e51a839f33ced64c6b36b6b64a2c225e52cdd8ef6c07d9f987604051611e5991815260200190565b60405180910390a35050600160065550505050565b6000600260065403611e925760405162461bcd60e51b8152600401610e7790613833565b60026006556007546201000090046001600160a01b03163314801590611ec357506010546001600160a01b03163314155b15611ee15760405163036c8cf960e11b815260040160405180910390fd5b82600003611f0257604051630e5a744960e41b815260040160405180910390fd5b6001600160a01b038216611f2957604051639fabe1c160e01b815260040160405180910390fd5b600e54831115611f4c57604051634cc7b59d60e01b815260040160405180910390fd5b611f54612735565b611f886001600160a01b037f0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f5168385612b7c565b82600e6000828254611f9a91906137e6565b90915550506040518381526001600160a01b038316907f0529afc4538720fe0b3eadc40486369ab962002d72fead1387b300c66073e7bf9060200160405180910390a25060018060065592915050565b6000610a1382611066565b6007546201000090046001600160a01b031633146120265760405163036c8cf960e11b815260040160405180910390fd5b6001600160a01b03811661204d57604051639fabe1c160e01b815260040160405180910390fd5b600b546001600160a01b039081169082160361207c5760405163367558c360e01b815260040160405180910390fd5b600b80546001600160a01b038381166001600160a01b0319831617909255604051633724df8760e21b8152908216917f0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f5169063dc937e1c906120e59085906000906004016138f2565b600060405180830381600087803b1580156120ff57600080fd5b505af1158015612113573d6000803e3d6000fd5b50506040516001600160a01b038086169350841691507f1703370ea1b3aaecb46974b10cd9534323f8b62d4b5c858e78c34ac64d4e329490600090a35050565b6040516370a0823160e01b815230600482015260009081906001600160a01b037f0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f516906370a0823190602401602060405180830381865afa1580156121bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121e091906137a4565b905080600e5410156121fe57600e546121f990826137e6565b612201565b60005b90506000612710600d546122136108c4565b61221d9190613891565b61222791906138b0565b9050808211612237576000612241565b61224181836137e6565b9250505090565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6007546201000090046001600160a01b031633146122a45760405163036c8cf960e11b815260040160405180910390fd5b600754610100900460ff16156122cc5760405162dc149f60e41b815260040160405180910390fd5b6007805461ff001916610100179055600b80546001600160a01b038085166001600160a01b031992831617909255600c80549284169290911691909117905561231d66038d7ea4c680003380612a23565b5050604051633724df8760e21b81526001600160a01b037f0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f5169063dc937e1c9061236e9085906000906004016138f2565b600060405180830381600087803b15801561238857600080fd5b505af115801561239c573d6000803e3d6000fd5b5050604051633724df8760e21b81526001600160a01b037f0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f516925063dc937e1c91506123ef9084906001906004016138f2565b600060405180830381600087803b15801561240957600080fd5b505af115801561241d573d6000803e3d6000fd5b50506040517f5daa87a0e9463431830481fd4b6e3403442dfb9a12b9c07597e9f61d50b633c8925060009150a15050565b6007546201000090046001600160a01b0316331461247f5760405163036c8cf960e11b815260040160405180910390fd5b6001600160a01b0381166124a657604051639fabe1c160e01b815260040160405180910390fd5b600c546001600160a01b03908116908216036124d55760405163367558c360e01b815260040160405180910390fd5b600c80546001600160a01b038381166001600160a01b0319831617909255604051633724df8760e21b8152908216917f0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f5169063dc937e1c9061253e9085906001906004016138f2565b600060405180830381600087803b15801561255857600080fd5b505af115801561256c573d6000803e3d6000fd5b50506040516001600160a01b038086169350841691507f97fb01cd0e4b307e0835da37ae485767ec7107d154a4abfb2b58f3730e6f4cef90600090a35050565b6001600160a01b03831615806125c957506001600160a01b038216155b156125e757604051632b65113b60e01b815260040160405180910390fd5b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6000805460000361266457506b033b2e3c9fd0803ce800000090565b61096b6000546126726108c4565b90612e3b565b6001600160a01b038316158061269557506001600160a01b038216155b156126b35760405163b53aab2360e01b815260040160405180910390fd5b816001600160a01b0316836001600160a01b0316036126e55760405163b3e918cb60e01b815260040160405180910390fd5b806000036127065760405163b3fcf27960e01b815260040160405180910390fd5b600061272261271d612716612648565b8490612e3b565b612e74565b905061272f848483612e9e565b50505050565b6040516346df7f7160e11b81523060048201527f0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f5906000906001600160a01b03831690638dbefee290602401602060405180830381865afa15801561279e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127c291906137a4565b9050801561285c576040516309a99b4f60e41b8152306004820152602481018290526001600160a01b03831690639a99b4f090604401600060405180830381600087803b15801561281257600080fd5b505af1158015612826573d6000803e3d6000fd5b50505050612710600f548261283b9190613891565b61284591906138b0565b600e600082825461285691906137d3565b90915550505b6040516370a0823160e01b81523060048201527f0000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae9906000906001600160a01b038316906370a0823190602401602060405180830381865afa1580156128c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128e991906137a4565b9050801561272f576129256001600160a01b0383167f0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f583612f57565b6040516356e4bb9760e11b8152306004820152602481018290526001600160a01b0385169063adc9772e90604401600060405180830381600087803b15801561296d57600080fd5b505af1158015612981573d6000803e3d6000fd5b5050505050505050565b612993613009565b6007805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60075460ff1615610ecd5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610e77565b6000806001600160a01b038416612a4d57604051639fabe1c160e01b815260040160405180910390fd5b84600003612a6e57604051630e5a744960e41b815260040160405180910390fd5b612a76612735565b6000612a80612648565b9050612ab76001600160a01b037f0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f516853089612be4565b6000612ac4868884613052565b969795505050505050565b6000816b019d971e4fe8401e7400000019048311820215612aef57600080fd5b506b033b2e3c9fd0803ce800000091026b019d971e4fe8401e74000000010490565b60006001600160f81b03821115612b3b57604051635a7eea2760e11b815260040160405180910390fd5b5090565b612b476129dd565b6007805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586129c03390565b6040516001600160a01b038316602482015260448101829052612bdf90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526131bd565b505050565b6040516001600160a01b038085166024830152831660448201526064810182905261272f9085906323b872dd60e01b90608401612ba8565b6000806001600160a01b0384161580612c3c57506001600160a01b038516155b15612c5a57604051639fabe1c160e01b815260040160405180910390fd5b85600003612c7b57604051630e5a744960e41b815260040160405180910390fd5b612c83612735565b60006000198703612c9e57612c9786611066565b9650600190505b836001600160a01b0316866001600160a01b031614612d3a576001600160a01b0380871660009081526001602090815260408083209388168352929052205487811015612cfe576040516364b3d8c760e01b815260040160405180910390fd5b6000198114612d3857612d1188826137e6565b6001600160a01b038089166000908152600160209081526040808320938a16835292905220555b505b6040516370a0823160e01b81523060048201527f0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f5906000906001600160a01b038316906370a0823190602401602060405180830381865afa158015612da3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dc791906137a4565b905080600e541015612de557600e54612de090826137e6565b612de8565b60005b905080891115612e0b576040516326f1bf9360e01b815260040160405180910390fd5b6000612e18898b8661328f565b9050612e2e6001600160a01b038416898c612b7c565b9899975050505050505050565b600281046b033b2e3c9fd0803ce80000008119048311158202612e5d57600080fd5b6b033b2e3c9fd0803ce80000009092029091010490565b60006001600160801b03821115612b3b57604051638ac92bf960e01b815260040160405180910390fd5b6001600160a01b0383166000908152600560205260409020546001600160801b039081169082161115612ee45760405163a50f989960e01b815260040160405180910390fd5b612ef88383836001600160801b0316613459565b6001600160a01b0392831660009081526005602052604080822080546001600160801b0380821686900381166fffffffffffffffffffffffffffffffff1992831617909255949095168252902080548085169092019093169116179055565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015612fa8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fcc91906137a4565b612fd691906137d3565b6040516001600160a01b03851660248201526044810182905290915061272f90859063095ea7b360e01b90606401612ba8565b60075460ff16610ecd5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610e77565b60008061305f8484612e3b565b9050806000036130825760405163b3fcf27960e01b815260040160405180910390fd5b61308e60008683613459565b61309783612e74565b6001600160a01b038616600090815260056020526040812080546001600160801b03938416600160801b02931692909217909155805482919081906130dd9084906137d3565b909155506130ec905081612e74565b6001600160a01b0386166000908152600560205260408120805490919061311d9084906001600160801b031661392d565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555060408051828152602081018590526001600160a01b038716917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a26040518481526001600160a01b038616906000906000805160206139ac8339815191529060200160405180910390a350919392505050565b6000613212826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166134899092919063ffffffff16565b805190915015612bdf5780806020019051810190613230919061394d565b612bdf5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610e77565b60008061329a612648565b6001600160a01b0386166000908152600560205260408120549192506001600160801b0390911690846132d6576132d18684612e3b565b6132d8565b815b9050806000036132fb5760405163b3fcf27960e01b815260040160405180910390fd5b8181111561331c5760405163a50f989960e01b815260040160405180910390fd5b61332887600083613459565b61333183612e74565b6001600160a01b038816600090815260056020526040812080546001600160801b03938416600160801b02931692909217909155805482919081906133779084906137e6565b90915550613386905081612e74565b6001600160a01b038816600090815260056020526040812080549091906133b79084906001600160801b031661396f565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555060408051828152602081018590526001600160a01b038916917f49995e5dd6158cf69ad3e9777c46755a1a826a446c6416992167462dad033b2a910160405180910390a26040518681526000906001600160a01b038916906000805160206139ac8339815191529060200160405180910390a3509395945050505050565b600754610100900460ff16613481576040516321c4e35760e21b815260040160405180910390fd5b612bdf6129dd565b606061349884846000856134a0565b949350505050565b6060824710156135015760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610e77565b6001600160a01b0385163b6135585760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610e77565b600080866001600160a01b03168587604051613574919061398f565b60006040518083038185875af1925050503d80600081146135b1576040519150601f19603f3d011682016040523d82523d6000602084013e6135b6565b606091505b50915091506135c68282866135d1565b979650505050505050565b606083156135e0575081610bd6565b8251156135f05782518084602001fd5b8160405162461bcd60e51b8152600401610e77919061362e565b60005b8381101561362557818101518382015260200161360d565b50506000910152565b602081526000825180602084015261364d81604085016020870161360a565b601f01601f19169190910160400192915050565b60006020828403121561367357600080fd5b5035919050565b80356001600160a01b038116811461166c57600080fd5b600080604083850312156136a457600080fd5b6136ad8361367a565b946020939093013593505050565b6000602082840312156136cd57600080fd5b610bd68261367a565b6000806000606084860312156136eb57600080fd5b6136f48461367a565b92506137026020850161367a565b9150604084013590509250925092565b6000806040838503121561372557600080fd5b823591506137356020840161367a565b90509250929050565b60008060006060848603121561375357600080fd5b833592506137636020850161367a565b91506137716040850161367a565b90509250925092565b6000806040838503121561378d57600080fd5b6137968361367a565b91506137356020840161367a565b6000602082840312156137b657600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610a1357610a136137bd565b81810381811115610a1357610a136137bd565b600181811c9082168061380d57607f821691505b60208210810361382d57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6001600160f81b0381811683821601908082111561388a5761388a6137bd565b5092915050565b60008160001904831182151516156138ab576138ab6137bd565b500290565b6000826138cd57634e487b7160e01b600052601260045260246000fd5b500490565b6001600160f81b0382811682821603908082111561388a5761388a6137bd565b6001600160a01b0383168152604081016002831061392057634e487b7160e01b600052602160045260246000fd5b8260208301529392505050565b6001600160801b0381811683821601908082111561388a5761388a6137bd565b60006020828403121561395f57600080fd5b81518015158114610bd657600080fd5b6001600160801b0382811682821603908082111561388a5761388a6137bd565b600082516139a181846020870161360a565b919091019291505056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122044f2632f32f061f871ee940d3dc81e0a314dab2e1f93c36e5c234813b9d9f70a64736f6c63430008100033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000bfd7a3dafed7c2d48b3374f6c4df946ba37395e500000000000000000000000000000000000000000000000000000000000001f4000000000000000000000000bfd7a3dafed7c2d48b3374f6c4df946ba37395e50000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae90000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f500000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000001044756c6c6168616e2073746b416176650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086473746b41415645000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _admin (address): 0xbFd7a3DafeD7C2d48b3374F6C4DF946bA37395e5
Arg [1] : _reserveRatio (uint256): 500
Arg [2] : _reserveManager (address): 0xbFd7a3DafeD7C2d48b3374F6C4DF946bA37395e5
Arg [3] : _aave (address): 0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9
Arg [4] : _stkAave (address): 0x4da27a545c0c5B758a6BA100e3a049001de870f5
Arg [5] : _name (string): Dullahan stkAave
Arg [6] : _symbol (string): dstkAAVE
-----Encoded View---------------
11 Constructor Arguments found :
Arg [0] : 000000000000000000000000bfd7a3dafed7c2d48b3374f6c4df946ba37395e5
Arg [1] : 00000000000000000000000000000000000000000000000000000000000001f4
Arg [2] : 000000000000000000000000bfd7a3dafed7c2d48b3374f6c4df946ba37395e5
Arg [3] : 0000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae9
Arg [4] : 0000000000000000000000004da27a545c0c5b758a6ba100e3a049001de870f5
Arg [5] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000010
Arg [8] : 44756c6c6168616e2073746b4161766500000000000000000000000000000000
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [10] : 6473746b41415645000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $308.63 | 1,014.7958 | $313,196.44 |
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.