Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 224 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Set Pause | 14497752 | 952 days ago | IN | 0 ETH | 0.00312354 | ||||
Repay Vault | 14484620 | 954 days ago | IN | 0 ETH | 0.00324615 | ||||
Report To Vault | 14484593 | 954 days ago | IN | 0 ETH | 0.00354089 | ||||
Repay Vault | 14465265 | 957 days ago | IN | 0 ETH | 0.00269614 | ||||
Report To Vault | 14465231 | 957 days ago | IN | 0 ETH | 0.00278824 | ||||
Report To Vault | 14446036 | 960 days ago | IN | 0 ETH | 0.00561669 | ||||
Repay Vault | 14426979 | 963 days ago | IN | 0 ETH | 0.00251247 | ||||
Report To Vault | 14426884 | 963 days ago | IN | 0 ETH | 0.00239799 | ||||
Borrow From Vaul... | 14407591 | 966 days ago | IN | 0 ETH | 0.0073823 | ||||
Report To Vault | 14407577 | 966 days ago | IN | 0 ETH | 0.00508312 | ||||
Repay Vault | 14388238 | 969 days ago | IN | 0 ETH | 0.00347974 | ||||
Report To Vault | 14388214 | 969 days ago | IN | 0 ETH | 0.00342804 | ||||
Borrow From Vaul... | 14369043 | 972 days ago | IN | 0 ETH | 0.00226649 | ||||
Report To Vault | 14369024 | 972 days ago | IN | 0 ETH | 0.00292927 | ||||
Repay Vault | 14349714 | 975 days ago | IN | 0 ETH | 0.00218386 | ||||
Report To Vault | 14349669 | 975 days ago | IN | 0 ETH | 0.00460264 | ||||
Borrow From Vaul... | 14330527 | 978 days ago | IN | 0 ETH | 0.00296493 | ||||
Borrow From Vaul... | 14330342 | 978 days ago | IN | 0 ETH | 0.00448334 | ||||
Report To Vault | 14330325 | 978 days ago | IN | 0 ETH | 0.00341363 | ||||
Repay Vault | 14311189 | 981 days ago | IN | 0 ETH | 0.00565795 | ||||
Report To Vault | 14311098 | 981 days ago | IN | 0 ETH | 0.00556839 | ||||
Borrow From Vaul... | 14302676 | 982 days ago | IN | 0 ETH | 0.01127402 | ||||
Borrow From Vaul... | 14291626 | 984 days ago | IN | 0 ETH | 0.00574921 | ||||
Report To Vault | 14291608 | 984 days ago | IN | 0 ETH | 0.00665949 | ||||
Borrow From Vaul... | 14272361 | 987 days ago | IN | 0 ETH | 0.00525871 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0x7C765C47...09071cba7 The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
Vyper_contract
Compiler Version
vyper:0.2.12
Contract Source Code (Vyper language format)
# @version 0.2.12 """ @title Unagii FundManager 0.1.1 @author stakewith.us @license AGPL-3.0-or-later """ from vyper.interfaces import ERC20 interface Vault: def token() -> address: view def debt() -> uint256: view def borrow(amount: uint256) -> uint256: nonpayable def repay(amount: uint256) -> uint256: nonpayable def report(gain: uint256, loss: uint256): nonpayable interface IStrategy: def fundManager() -> address: view def token() -> address: view def withdraw(amount: uint256) -> uint256: nonpayable def migrate(newVersion: address): nonpayable # interface to new version of FundManager used for migration interface FundManager: def token() -> address: view def vault() -> address: view def totalDebt() -> uint256: view def totalDebtRatio() -> uint256: view def queue(i: uint256) -> address: view def strategies( addr: address, ) -> (bool, bool, bool, uint256, uint256, uint256, uint256): view def initialize(): nonpayable # maximum number of active strategies MAX_QUEUE: constant(uint256) = 20 struct Strategy: approved: bool active: bool activated: bool # sent to True once after strategy is active debtRatio: uint256 # ratio of total assets this strategy can borrow debt: uint256 # current amount borrowed minBorrow: uint256 # minimum amount to borrow per call to borrow() maxBorrow: uint256 # maximum amount to borrow per call to borrow() event SetNextTimeLock: nextTimeLock: address event AcceptTimeLock: timeLock: address event SetAdmin: admin: address event SetGuardian: guardian: address event SetWorker: worker: address event SetPause: paused: bool event SetVault: vault: address event ApproveStrategy: strategy: indexed(address) event RevokeStrategy: strategy: indexed(address) event AddStrategyToQueue: strategy: indexed(address) event RemoveStrategyFromQueue: strategy: indexed(address) event SetQueue: queue: address[MAX_QUEUE] event SetDebtRatios: debtRatios: uint256[MAX_QUEUE] event SetMinMaxBorrow: strategy: indexed(address) minBorrow: uint256 maxBorrow: uint256 event BorrowFromVault: vault: indexed(address) amount: uint256 borrowed: uint256 event RepayVault: vault: indexed(address) amount: uint256 repaid: uint256 event ReportToVault: vault: indexed(address) total: uint256 debt: uint256 gain: uint256 loss: uint256 event Withdraw: vault: indexed(address) amount: uint256 actual: uint256 loss: uint256 event WithdrawStrategy: strategy: indexed(address) debt: uint256 need: uint256 loss: uint256 diff: uint256 event Borrow: strategy: indexed(address) amount: uint256 borrowed: uint256 event Repay: strategy: indexed(address) amount: uint256 repaid: uint256 event Report: strategy: indexed(address) gain: uint256 loss: uint256 debt: uint256 event MigrateStrategy: oldStrategy: indexed(address) newStrategy: indexed(address) event Migrate: fundManager: address bal: uint256 totalDebt: uint256 paused: public(bool) initialized: public(bool) vault: public(Vault) token: public(ERC20) # privileges - time lock >= admin >= guardian, worker timeLock: public(address) nextTimeLock: public(address) admin: public(address) guardian: public(address) worker: public(address) totalDebt: public(uint256) # sum of all debts of strategies MAX_TOTAL_DEBT_RATIO: constant(uint256) = 10000 totalDebtRatio: public(uint256) # sum of all debtRatios of strategies strategies: public(HashMap[address, Strategy]) # all strategies queue: public(address[MAX_QUEUE]) # list of active strategies # migration OLD_MAX_QUEUE: constant(uint256) = 20 # must be <= MAX_QUEUE oldFundManager: public(FundManager) @external def __init__( token: address, guardian: address, worker: address, oldFundManager: address ): self.token = ERC20(token) self.timeLock = msg.sender self.admin = msg.sender self.guardian = guardian self.worker = worker if oldFundManager != ZERO_ADDRESS: self.oldFundManager = FundManager(oldFundManager) assert self.oldFundManager.token() == token, "old fund manager token != token" @internal def _safeApprove(token: address, spender: address, amount: uint256): res: Bytes[32] = raw_call( token, concat( method_id("approve(address,uint256)"), convert(spender, bytes32), convert(amount, bytes32), ), max_outsize=32, ) if len(res) > 0: assert convert(res, bool), "approve failed" @internal def _safeTransfer(token: address, receiver: address, amount: uint256): res: Bytes[32] = raw_call( token, concat( method_id("transfer(address,uint256)"), convert(receiver, bytes32), convert(amount, bytes32), ), max_outsize=32, ) if len(res) > 0: assert convert(res, bool), "transfer failed" @internal def _safeTransferFrom( token: address, owner: address, receiver: address, amount: uint256 ): res: Bytes[32] = raw_call( token, concat( method_id("transferFrom(address,address,uint256)"), convert(owner, bytes32), convert(receiver, bytes32), convert(amount, bytes32), ), max_outsize=32, ) if len(res) > 0: assert convert(res, bool), "transferFrom failed" @external def initialize(): """ @notice Initialize fund manager. Transfer tokens and copy states if old fund manager is set. """ assert not self.initialized, "initialized" if self.oldFundManager.address == ZERO_ADDRESS: assert msg.sender in [self.timeLock, self.admin], "!auth" else: assert msg.sender == self.oldFundManager.address, "!old fund manager" assert ( self.vault.address == self.oldFundManager.vault() ), "old fund manager vault != vault" bal: uint256 = self.token.balanceOf(self.oldFundManager.address) self._safeTransferFrom( self.token.address, self.oldFundManager.address, self, bal ) self.totalDebt = self.oldFundManager.totalDebt() self.totalDebtRatio = self.oldFundManager.totalDebtRatio() for i in range(OLD_MAX_QUEUE): addr: address = self.oldFundManager.queue(i) if addr == ZERO_ADDRESS: break assert ( IStrategy(addr).fundManager() == self ), "strategy fund manager != self" approved: bool = False active: bool = False activated: bool = False debtRatio: uint256 = 0 debt: uint256 = 0 minBorrow: uint256 = 0 maxBorrow: uint256 = 0 ( approved, active, activated, debtRatio, debt, minBorrow, maxBorrow, ) = self.oldFundManager.strategies(addr) assert approved, "!approved" assert active, "!active" assert activated, "!activated" self.queue[i] = addr self.strategies[addr] = Strategy( { approved: True, active: True, activated: True, debtRatio: debtRatio, debt: debt, minBorrow: minBorrow, maxBorrow: maxBorrow, } ) self.initialized = True # Migration steps to new fund manager # # t = token # v = vault # f1 = fund manager 1 # f2 = fund manager 2 # strats = active strategies of f1 # # action | caller # ---------------------------------------- # 1. f2.setVault(v) | time lock # 2. f1.setPause(true) | admin # 3. for s in strats | # s.setFundManager(f2) | time lock # 4. t.approve(f2, bal) | f1 # 5. t.transferFrom(f1, f2, bal) | f2 # 6. f2 copy states from f1 | f2 # - totalDebt | # - totalDebtRatio | # - queue | # - active strategy params | # 7. f1 reset state | f1 # - totalDebt | # - active strategy debt | # 8. v.setFundManager(f2) | time lock @external def migrate(fundManager: address): """ @notice Migrate to new fund manager @param fundManager Address of new fund manager """ assert msg.sender == self.timeLock, "!time lock" assert self.initialized, "!initialized" assert self.paused, "!paused" assert ( FundManager(fundManager).token() == self.token.address ), "new fund manager token != token" assert ( FundManager(fundManager).vault() == self.vault.address ), "new fund manager vault != vault" for strat in self.queue: if strat == ZERO_ADDRESS: break assert ( IStrategy(strat).fundManager() == fundManager ), "strategy fund manager != new fund manager" bal: uint256 = self.token.balanceOf(self) self._safeApprove(self.token.address, fundManager, bal) FundManager(fundManager).initialize() assert self.token.balanceOf(self) == 0, "bal != 0" log Migrate(fundManager, bal, self.totalDebt) self.totalDebt = 0 for strat in self.queue: if strat == ZERO_ADDRESS: break self.strategies[strat].debt = 0 @external def setNextTimeLock(nextTimeLock: address): """ @notice Set next time lock @param nextTimeLock Address of next time lock """ assert msg.sender == self.timeLock, "!time lock" self.nextTimeLock = nextTimeLock log SetNextTimeLock(nextTimeLock) @external def acceptTimeLock(): """ @notice Accept time lock @dev Only `nextTimeLock` can claim time lock """ assert msg.sender == self.nextTimeLock, "!next time lock" self.timeLock = msg.sender self.nextTimeLock = ZERO_ADDRESS log AcceptTimeLock(msg.sender) @external def setAdmin(admin: address): assert msg.sender in [self.timeLock, self.admin], "!auth" self.admin = admin log SetAdmin(admin) @external def setGuardian(guardian: address): assert msg.sender in [self.timeLock, self.admin], "!auth" self.guardian = guardian log SetGuardian(guardian) @external def setWorker(worker: address): assert msg.sender in [self.timeLock, self.admin], "!auth" self.worker = worker log SetWorker(worker) @external def setPause(paused: bool): assert msg.sender in [self.timeLock, self.admin, self.guardian], "!auth" self.paused = paused log SetPause(paused) @external def setVault(vault: address): """ @notice Set vault @param vault Address of vault """ assert msg.sender == self.timeLock, "!time lock" assert Vault(vault).token() == self.token.address, "vault token != token" if self.vault.address != ZERO_ADDRESS: self._safeApprove(self.token.address, self.vault.address, 0) self.vault = Vault(vault) self._safeApprove(self.token.address, self.vault.address, MAX_UINT256) log SetVault(vault) @internal @view def _totalAssets() -> uint256: """ @notice Total amount of token in this fund manager + total amount borrowed by strategies @dev Returns total amount of token managed by this contract """ return self.token.balanceOf(self) + self.totalDebt @external @view def totalAssets() -> uint256: return self._totalAssets() # array functions tested in test/Array.vy @internal def _pack(): arr: address[MAX_QUEUE] = empty(address[MAX_QUEUE]) i: uint256 = 0 for strat in self.queue: if strat != ZERO_ADDRESS: arr[i] = strat i += 1 self.queue = arr @internal def _append(strategy: address): assert self.queue[MAX_QUEUE - 1] == ZERO_ADDRESS, "queue > max" self.queue[MAX_QUEUE - 1] = strategy self._pack() @internal def _remove(i: uint256): assert i < MAX_QUEUE, "i >= max" assert self.queue[i] != ZERO_ADDRESS, "!zero address" self.queue[i] = ZERO_ADDRESS self._pack() @internal @view def _find(strategy: address) -> uint256: for i in range(MAX_QUEUE): if self.queue[i] == strategy: return i raise "not found" @external def approveStrategy(strategy: address): """ @notice Approve strategy @param strategy Address of strategy """ assert msg.sender == self.timeLock, "!time lock" assert not self.strategies[strategy].approved, "approved" assert IStrategy(strategy).fundManager() == self, "strategy fund manager != this" assert IStrategy(strategy).token() == self.token.address, "strategy token != token" self.strategies[strategy] = Strategy( { approved: True, active: False, activated: False, debtRatio: 0, debt: 0, minBorrow: 0, maxBorrow: 0, } ) log ApproveStrategy(strategy) @external def revokeStrategy(strategy: address): """ @notice Disapprove strategy @param strategy Address of strategy """ assert msg.sender in [self.timeLock, self.admin], "!auth" assert self.strategies[strategy].approved, "!approved" assert not self.strategies[strategy].active, "active" self.strategies[strategy].approved = False log RevokeStrategy(strategy) @external def addStrategyToQueue( strategy: address, debtRatio: uint256, minBorrow: uint256, maxBorrow: uint256 ): """ @notice Activate strategy @param strategy Address of strategy @param debtRatio Ratio of total assets this strategy can borrow @param minBorrow Minimum amount to borrow per call to borrow() @param maxBorrow Maximum amount to borrow per call to borrow() """ assert msg.sender in [self.timeLock, self.admin], "!auth" assert self.strategies[strategy].approved, "!approved" assert not self.strategies[strategy].active, "active" assert self.totalDebtRatio + debtRatio <= MAX_TOTAL_DEBT_RATIO, "ratio > max" assert minBorrow <= maxBorrow, "min borrow > max borrow" self._append(strategy) self.strategies[strategy].active = True self.strategies[strategy].activated = True self.strategies[strategy].debtRatio = debtRatio self.strategies[strategy].minBorrow = minBorrow self.strategies[strategy].maxBorrow = maxBorrow self.totalDebtRatio += debtRatio log AddStrategyToQueue(strategy) @external def removeStrategyFromQueue(strategy: address): """ @notice Deactivate strategy @param strategy Addres of strategy """ assert msg.sender in [self.timeLock, self.admin, self.guardian], "!auth" assert self.strategies[strategy].active, "!active" self._remove(self._find(strategy)) self.strategies[strategy].active = False self.totalDebtRatio -= self.strategies[strategy].debtRatio self.strategies[strategy].debtRatio = 0 log RemoveStrategyFromQueue(strategy) @external def setQueue(queue: address[MAX_QUEUE]): """ @notice Reorder queue @param queue Array of active strategies """ assert msg.sender in [self.timeLock, self.admin], "!auth" # check no gaps in new queue zero: bool = False for i in range(MAX_QUEUE): strat: address = queue[i] if strat == ZERO_ADDRESS: if not zero: zero = True else: assert not zero, "gap" # Check old and new queue counts of non zero strategies are equal for i in range(MAX_QUEUE): oldStrat: address = self.queue[i] newStrat: address = queue[i] if oldStrat == ZERO_ADDRESS: assert newStrat == ZERO_ADDRESS, "new != 0" else: assert newStrat != ZERO_ADDRESS, "new = 0" # Check new strategy is active and no duplicate for i in range(MAX_QUEUE): strat: address = queue[i] if strat == ZERO_ADDRESS: break # code below will fail if duplicate strategy in new queue assert self.strategies[strat].active, "!active" self.strategies[strat].active = False # update queue for i in range(MAX_QUEUE): strat: address = queue[i] if strat == ZERO_ADDRESS: break self.strategies[strat].active = True self.queue[i] = strat log SetQueue(queue) @external def setDebtRatios(debtRatios: uint256[MAX_QUEUE]): """ @notice Update debt ratios of active strategies @param debtRatios Array of debt ratios """ assert msg.sender in [self.timeLock, self.admin], "!auth" # check that we're only setting debt ratio on active strategy for i in range(MAX_QUEUE): if self.queue[i] == ZERO_ADDRESS: assert debtRatios[i] == 0, "debt ratio != 0" # use memory to save gas totalDebtRatio: uint256 = 0 for i in range(MAX_QUEUE): addr: address = self.queue[i] if addr == ZERO_ADDRESS: break debtRatio: uint256 = debtRatios[i] self.strategies[addr].debtRatio = debtRatio totalDebtRatio += debtRatio self.totalDebtRatio = totalDebtRatio assert self.totalDebtRatio <= MAX_TOTAL_DEBT_RATIO, "total > max" log SetDebtRatios(debtRatios) @external def setMinMaxBorrow(strategy: address, minBorrow: uint256, maxBorrow: uint256): """ @notice Update `minBorrow` and `maxBorrow` of approved strategy @param minBorrow Minimum amount to borrow per call to borrow() @param maxBorrow Maximum amount to borrow per call to borrow() """ assert msg.sender in [self.timeLock, self.admin], "!auth" assert self.strategies[strategy].approved, "!approved" assert minBorrow <= maxBorrow, "min borrow > max borrow" self.strategies[strategy].minBorrow = minBorrow self.strategies[strategy].maxBorrow = maxBorrow log SetMinMaxBorrow(strategy, minBorrow, maxBorrow) # functions between Vault and this contract # @external def borrowFromVault(amount: uint256, _min: uint256): """ @notice Borrow `token` from vault @param amount Amount of token to borrow @param _min Minimum amount to borrow """ assert self.initialized, "!initialized" assert msg.sender in [self.timeLock, self.admin, self.worker], "!auth" # fails if vault not set borrowed: uint256 = self.vault.borrow(amount) assert borrowed >= _min, "borrowed < min" log BorrowFromVault(self.vault.address, amount, borrowed) @external def repayVault(amount: uint256, _min: uint256): """ @notice Repay `token` to vault @param amount Amount to repay @param _min Minimum amount to repay """ assert self.initialized, "!initialized" assert msg.sender in [self.timeLock, self.admin, self.worker], "!auth" # fails if vault not set # infinite approved in setVault() repaid: uint256 = self.vault.repay(amount) assert repaid >= _min, "repaid < min" log RepayVault(self.vault.address, amount, repaid) @external def reportToVault(_minTotal: uint256, _maxTotal: uint256): """ @notice Report gain and loss to vault @param _minTotal Minumum of total assets @param _maxTotal Maximum of total assets @dev `_minTotal` and `_maxTotal` is used to check that totalAssets is within a reasonable range before this function is called """ assert self.initialized, "!initialized" assert msg.sender in [self.timeLock, self.admin, self.worker], "!auth" total: uint256 = self._totalAssets() assert total >= _minTotal and total <= _maxTotal, "total not in range" debt: uint256 = self.vault.debt() gain: uint256 = 0 loss: uint256 = 0 if total > debt: # token.balanceOf(self) = total - self.totalDebt gain = min(total - debt, total - self.totalDebt) else: loss = debt - total if gain > 0 or loss > 0: self.vault.report(gain, loss) log ReportToVault(self.vault.address, total, debt, gain, loss) # functions between vault -> this contract -> strategies # @internal def _withdraw(amount: uint256) -> uint256: """ @notice Withdraw `token` from active strategies @param amount Amount of `token` to withdraw @dev Returns sum of losses from active strategies that were withdrawn. """ _amount: uint256 = amount totalLoss: uint256 = 0 for strategy in self.queue: if strategy == ZERO_ADDRESS: break bal: uint256 = self.token.balanceOf(self) if bal >= _amount: break debt: uint256 = self.strategies[strategy].debt need: uint256 = min(_amount - bal, debt) if need == 0: continue # loss must be <= debt loss: uint256 = IStrategy(strategy).withdraw(need) diff: uint256 = self.token.balanceOf(self) - bal if loss > 0: _amount -= loss totalLoss += loss self.strategies[strategy].debt -= loss self.totalDebt -= loss self.strategies[strategy].debt -= diff self.totalDebt -= diff log WithdrawStrategy(strategy, debt, need, loss, diff) return totalLoss @external def withdraw(amount: uint256) -> uint256: """ @notice Withdraw `token` from fund manager back to vault @param amount Amount of `token` to withdraw @dev Returns sum of losses from active strategies that were withdrawn. """ assert self.initialized, "!initialized" assert msg.sender == self.vault.address, "!vault" total: uint256 = self._totalAssets() _amount: uint256 = min(amount, total) assert _amount > 0, "withdraw = 0" debt: uint256 = self.vault.debt() loss: uint256 = 0 if debt > total: # debt > total can occur when strategies reported losses to this contract # but this contract has not reported losses back to vault loss = debt - total bal: uint256 = self.token.balanceOf(self) if _amount > bal: # try to withdraw until balance of fund manager >= _amount loss += self._withdraw(_amount) _amount = min(_amount, self.token.balanceOf(self)) if _amount > 0: self._safeTransfer(self.token.address, msg.sender, _amount) log Withdraw(msg.sender, amount, _amount, loss) return loss # functions between this contract and strategies # @internal @view def _calcMaxBorrow(strategy: address) -> uint256: """ @notice Calculate how much `token` strategy can borrow @param strategy Address of strategy @dev Returns amount of `token` that `strategy` can borrow """ if (not self.initialized) or self.paused or self.totalDebtRatio == 0: return 0 # strategy debtRatio > 0 only if strategy is active limit: uint256 = ( self.strategies[strategy].debtRatio * self._totalAssets() / self.totalDebtRatio ) debt: uint256 = self.strategies[strategy].debt if debt >= limit: return 0 available: uint256 = min(limit - debt, self.token.balanceOf(self)) if available < self.strategies[strategy].minBorrow: return 0 else: return min(available, self.strategies[strategy].maxBorrow) @external @view def calcMaxBorrow(strategy: address) -> uint256: return self._calcMaxBorrow(strategy) @internal @view def _calcOutstandingDebt(strategy: address) -> uint256: """ @notice Calculate amount of `token` that `strategy` should pay back to fund manager @param strategy Address of strategy @dev Returns minimum amount of `token` strategy should repay """ if not self.initialized: return 0 if self.totalDebtRatio == 0: return self.strategies[strategy].debt limit: uint256 = ( self.strategies[strategy].debtRatio * self.totalDebt / self.totalDebtRatio ) debt: uint256 = self.strategies[strategy].debt if self.paused: return debt elif debt <= limit: return 0 else: return debt - limit @external @view def calcOutstandingDebt(strategy: address) -> uint256: return self._calcOutstandingDebt(strategy) @external @view def getDebt(strategy: address) -> uint256: """ @notice Return debt of strategy @param strategy Address of strategy @dev Returns current debt of strategy """ return self.strategies[strategy].debt @external @nonreentrant("lock") def borrow(amount: uint256) -> uint256: """ @notice Borrow `token` from fund manager @param amount Amount of `token` to borrow @dev Returns actual amount sent @dev Only active strategy can borrow """ assert self.initialized, "!initialized" assert not self.paused, "paused" assert self.strategies[msg.sender].active, "!active" _amount: uint256 = min(amount, self._calcMaxBorrow(msg.sender)) assert _amount > 0, "borrow = 0" self._safeTransfer(self.token.address, msg.sender, _amount) # include any fee on transfer to debt self.strategies[msg.sender].debt += _amount self.totalDebt += _amount log Borrow(msg.sender, amount, _amount) return _amount @external def repay(amount: uint256) -> uint256: """ @notice Repay debt to fund manager @param amount Amount of `token` to repay @dev Returns actual amount repaid @dev Only approved strategy can repay """ assert self.initialized, "!initialized" assert self.strategies[msg.sender].approved, "!approved" _amount: uint256 = min(amount, self.strategies[msg.sender].debt) assert _amount > 0, "repay = 0" diff: uint256 = self.token.balanceOf(self) self._safeTransferFrom(self.token.address, msg.sender, self, _amount) diff = self.token.balanceOf(self) - diff # exclude fee on transfer from debt payment self.strategies[msg.sender].debt -= diff self.totalDebt -= diff log Repay(msg.sender, amount, diff) return diff @external def report(gain: uint256, loss: uint256): """ @notice Report gain and loss from strategy @param gain Amount of profit @param loss Amount of loss """ assert self.initialized, "!initialized" assert self.strategies[msg.sender].active, "!active" # can't have both gain and loss > 0 assert (gain >= 0 and loss == 0) or (gain == 0 and loss >= 0), "gain and loss > 0" if gain > 0: self._safeTransferFrom(self.token.address, msg.sender, self, gain) elif loss > 0: self.strategies[msg.sender].debt -= loss self.totalDebt -= loss log Report(msg.sender, gain, loss, self.strategies[msg.sender].debt) @external def migrateStrategy(oldStrat: address, newStrat: address): """ @notice Migrate strategy @param oldStrat Address of current strategy @param newStrat Address of strategy to migrate to """ assert self.initialized, "!initialized" assert msg.sender in [self.timeLock, self.admin], "!auth" assert self.strategies[oldStrat].active, "old !active" assert self.strategies[newStrat].approved, "new !approved" assert not self.strategies[newStrat].activated, "activated" strat: Strategy = self.strategies[oldStrat] self.strategies[newStrat] = Strategy( { approved: True, active: True, activated: True, debtRatio: strat.debtRatio, debt: strat.debt, minBorrow: strat.minBorrow, maxBorrow: strat.maxBorrow, } ) self.strategies[oldStrat].active = False self.strategies[oldStrat].debtRatio = 0 self.strategies[oldStrat].debt = 0 self.strategies[oldStrat].minBorrow = 0 self.strategies[oldStrat].maxBorrow = 0 # find and replace strategy i: uint256 = self._find(oldStrat) self.queue[i] = newStrat IStrategy(oldStrat).migrate(newStrat) log MigrateStrategy(oldStrat, newStrat) @external def sweep(token: address): """ @notice Transfer any token (except `token`) accidentally sent to this contract to admin or time lock @dev Cannot transfer `token` """ assert msg.sender in [self.timeLock, self.admin], "!auth" assert token != self.token.address, "protected" self._safeTransfer(token, msg.sender, ERC20(token).balanceOf(self))
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"name":"SetNextTimeLock","inputs":[{"name":"nextTimeLock","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"AcceptTimeLock","inputs":[{"name":"timeLock","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"SetAdmin","inputs":[{"name":"admin","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"SetGuardian","inputs":[{"name":"guardian","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"SetWorker","inputs":[{"name":"worker","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"SetPause","inputs":[{"name":"paused","type":"bool","indexed":false}],"anonymous":false,"type":"event"},{"name":"SetVault","inputs":[{"name":"vault","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"ApproveStrategy","inputs":[{"name":"strategy","type":"address","indexed":true}],"anonymous":false,"type":"event"},{"name":"RevokeStrategy","inputs":[{"name":"strategy","type":"address","indexed":true}],"anonymous":false,"type":"event"},{"name":"AddStrategyToQueue","inputs":[{"name":"strategy","type":"address","indexed":true}],"anonymous":false,"type":"event"},{"name":"RemoveStrategyFromQueue","inputs":[{"name":"strategy","type":"address","indexed":true}],"anonymous":false,"type":"event"},{"name":"SetQueue","inputs":[{"name":"queue","type":"address[20]","indexed":false}],"anonymous":false,"type":"event"},{"name":"SetDebtRatios","inputs":[{"name":"debtRatios","type":"uint256[20]","indexed":false}],"anonymous":false,"type":"event"},{"name":"SetMinMaxBorrow","inputs":[{"name":"strategy","type":"address","indexed":true},{"name":"minBorrow","type":"uint256","indexed":false},{"name":"maxBorrow","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"BorrowFromVault","inputs":[{"name":"vault","type":"address","indexed":true},{"name":"amount","type":"uint256","indexed":false},{"name":"borrowed","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"RepayVault","inputs":[{"name":"vault","type":"address","indexed":true},{"name":"amount","type":"uint256","indexed":false},{"name":"repaid","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"ReportToVault","inputs":[{"name":"vault","type":"address","indexed":true},{"name":"total","type":"uint256","indexed":false},{"name":"debt","type":"uint256","indexed":false},{"name":"gain","type":"uint256","indexed":false},{"name":"loss","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"Withdraw","inputs":[{"name":"vault","type":"address","indexed":true},{"name":"amount","type":"uint256","indexed":false},{"name":"actual","type":"uint256","indexed":false},{"name":"loss","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"WithdrawStrategy","inputs":[{"name":"strategy","type":"address","indexed":true},{"name":"debt","type":"uint256","indexed":false},{"name":"need","type":"uint256","indexed":false},{"name":"loss","type":"uint256","indexed":false},{"name":"diff","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"Borrow","inputs":[{"name":"strategy","type":"address","indexed":true},{"name":"amount","type":"uint256","indexed":false},{"name":"borrowed","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"Repay","inputs":[{"name":"strategy","type":"address","indexed":true},{"name":"amount","type":"uint256","indexed":false},{"name":"repaid","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"Report","inputs":[{"name":"strategy","type":"address","indexed":true},{"name":"gain","type":"uint256","indexed":false},{"name":"loss","type":"uint256","indexed":false},{"name":"debt","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"MigrateStrategy","inputs":[{"name":"oldStrategy","type":"address","indexed":true},{"name":"newStrategy","type":"address","indexed":true}],"anonymous":false,"type":"event"},{"name":"Migrate","inputs":[{"name":"fundManager","type":"address","indexed":false},{"name":"bal","type":"uint256","indexed":false},{"name":"totalDebt","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"stateMutability":"nonpayable","type":"constructor","inputs":[{"name":"token","type":"address"},{"name":"guardian","type":"address"},{"name":"worker","type":"address"},{"name":"oldFundManager","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"initialize","inputs":[],"outputs":[],"gas":6015090},{"stateMutability":"nonpayable","type":"function","name":"migrate","inputs":[{"name":"fundManager","type":"address"}],"outputs":[],"gas":614975},{"stateMutability":"nonpayable","type":"function","name":"setNextTimeLock","inputs":[{"name":"nextTimeLock","type":"address"}],"outputs":[],"gas":38981},{"stateMutability":"nonpayable","type":"function","name":"acceptTimeLock","inputs":[],"outputs":[],"gas":58909},{"stateMutability":"nonpayable","type":"function","name":"setAdmin","inputs":[{"name":"admin","type":"address"}],"outputs":[],"gas":41562},{"stateMutability":"nonpayable","type":"function","name":"setGuardian","inputs":[{"name":"guardian","type":"address"}],"outputs":[],"gas":41592},{"stateMutability":"nonpayable","type":"function","name":"setWorker","inputs":[{"name":"worker","type":"address"}],"outputs":[],"gas":41622},{"stateMutability":"nonpayable","type":"function","name":"setPause","inputs":[{"name":"paused","type":"bool"}],"outputs":[],"gas":43920},{"stateMutability":"nonpayable","type":"function","name":"setVault","inputs":[{"name":"vault","type":"address"}],"outputs":[],"gas":74660},{"stateMutability":"view","type":"function","name":"totalAssets","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":7978},{"stateMutability":"nonpayable","type":"function","name":"approveStrategy","inputs":[{"name":"strategy","type":"address"}],"outputs":[],"gas":168784},{"stateMutability":"nonpayable","type":"function","name":"revokeStrategy","inputs":[{"name":"strategy","type":"address"}],"outputs":[],"gas":31536},{"stateMutability":"nonpayable","type":"function","name":"addStrategyToQueue","inputs":[{"name":"strategy","type":"address"},{"name":"debtRatio","type":"uint256"},{"name":"minBorrow","type":"uint256"},{"name":"maxBorrow","type":"uint256"}],"outputs":[],"gas":1773661},{"stateMutability":"nonpayable","type":"function","name":"removeStrategyFromQueue","inputs":[{"name":"strategy","type":"address"}],"outputs":[],"gas":1672791},{"stateMutability":"nonpayable","type":"function","name":"setQueue","inputs":[{"name":"queue","type":"address[20]"}],"outputs":[],"gas":1941136},{"stateMutability":"nonpayable","type":"function","name":"setDebtRatios","inputs":[{"name":"debtRatios","type":"uint256[20]"}],"outputs":[],"gas":861988},{"stateMutability":"nonpayable","type":"function","name":"setMinMaxBorrow","inputs":[{"name":"strategy","type":"address"},{"name":"minBorrow","type":"uint256"},{"name":"maxBorrow","type":"uint256"}],"outputs":[],"gas":80796},{"stateMutability":"nonpayable","type":"function","name":"borrowFromVault","inputs":[{"name":"amount","type":"uint256"},{"name":"_min","type":"uint256"}],"outputs":[],"gas":18996},{"stateMutability":"nonpayable","type":"function","name":"repayVault","inputs":[{"name":"amount","type":"uint256"},{"name":"_min","type":"uint256"}],"outputs":[],"gas":19026},{"stateMutability":"nonpayable","type":"function","name":"reportToVault","inputs":[{"name":"_minTotal","type":"uint256"},{"name":"_maxTotal","type":"uint256"}],"outputs":[],"gas":39513},{"stateMutability":"nonpayable","type":"function","name":"withdraw","inputs":[{"name":"amount","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":3452159},{"stateMutability":"view","type":"function","name":"calcMaxBorrow","inputs":[{"name":"strategy","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":40029},{"stateMutability":"view","type":"function","name":"calcOutstandingDebt","inputs":[{"name":"strategy","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":20463},{"stateMutability":"view","type":"function","name":"getDebt","inputs":[{"name":"strategy","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":3371},{"stateMutability":"nonpayable","type":"function","name":"borrow","inputs":[{"name":"amount","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":213592},{"stateMutability":"nonpayable","type":"function","name":"repay","inputs":[{"name":"amount","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":106756},{"stateMutability":"nonpayable","type":"function","name":"report","inputs":[{"name":"gain","type":"uint256"},{"name":"loss","type":"uint256"}],"outputs":[],"gas":85897},{"stateMutability":"nonpayable","type":"function","name":"migrateStrategy","inputs":[{"name":"oldStrat","type":"address"},{"name":"newStrat","type":"address"}],"outputs":[],"gas":468697},{"stateMutability":"nonpayable","type":"function","name":"sweep","inputs":[{"name":"token","type":"address"}],"outputs":[],"gas":20791},{"stateMutability":"view","type":"function","name":"paused","inputs":[],"outputs":[{"name":"","type":"bool"}],"gas":3258},{"stateMutability":"view","type":"function","name":"initialized","inputs":[],"outputs":[{"name":"","type":"bool"}],"gas":3288},{"stateMutability":"view","type":"function","name":"vault","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":3318},{"stateMutability":"view","type":"function","name":"token","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":3348},{"stateMutability":"view","type":"function","name":"timeLock","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":3378},{"stateMutability":"view","type":"function","name":"nextTimeLock","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":3408},{"stateMutability":"view","type":"function","name":"admin","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":3438},{"stateMutability":"view","type":"function","name":"guardian","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":3468},{"stateMutability":"view","type":"function","name":"worker","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":3498},{"stateMutability":"view","type":"function","name":"totalDebt","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3528},{"stateMutability":"view","type":"function","name":"totalDebtRatio","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3558},{"stateMutability":"view","type":"function","name":"strategies","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"approved","type":"bool"},{"name":"active","type":"bool"},{"name":"activated","type":"bool"},{"name":"debtRatio","type":"uint256"},{"name":"debt","type":"uint256"},{"name":"minBorrow","type":"uint256"},{"name":"maxBorrow","type":"uint256"}],"gas":17747},{"stateMutability":"view","type":"function","name":"queue","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"address"}],"gas":3727},{"stateMutability":"view","type":"function","name":"oldFundManager","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":3648}]
Deployed Bytecode
0x600436101561000d57613fde565b600035601c52600051341561002157600080fd5b638129fc1c8114156106365760015415151561007c576308c379a061014052602061016052600b610180527f696e697469616c697a65640000000000000000000000000000000000000000006101a05261018050606461015cfd5b600d54151561012b57600454610160526006546101805260006101405261014061012060006002818352015b6101205160200261016001513314156100c457600183526100d4565b81516001018083528114156100a8575b505050610140511515610126576308c379a06101a05260206101c05260056101e0527f2161757468000000000000000000000000000000000000000000000000000000610200526101e05060646101bcfd5b61062f565b600d543314151561017b576308c379a0610140526020610160526011610180527f216f6c642066756e64206d616e616765720000000000000000000000000000006101a05261018050606461015cfd5b60206101a0600463fbfa77cf6101405261015c600d545afa61019c57600080fd5b601f3d116101a957600080fd5b6000506101a0516002541415156101ff576308c379a06101c05260206101e052601f610200527f6f6c642066756e64206d616e61676572207661756c7420213d207661756c7400610220526102005060646101dcfd5b60206101e060246370a0823161016052600d546101805261017c6003545afa61022757600080fd5b601f3d1161023457600080fd5b6000506101e051610140526101405160035461016052600d5461018052306101a052610140516101c0526101c0516101a051610180516101605160065801614318565b6101405260005060206101c0600463fc7b9c186101605261017c600d545afa61029f57600080fd5b601f3d116102ac57600080fd5b6000506101c05160095560206101c06004632df9eab96101605261017c600d545afa6102d757600080fd5b601f3d116102e457600080fd5b6000506101c051600a5561016060006014818352015b6020610220602463ddf0b0096101a052610160516101c0526101bc600d545afa61032357600080fd5b601f3d1161033057600080fd5b600050610220516101805261018051151561034a5761062c565b3060206102006004636209ec2d6101a0526101bc610180515afa61036d57600080fd5b601f3d1161037a57600080fd5b600050610200511415156103cd576308c379a061022052602061024052601d610260527f73747261746567792066756e64206d616e6167657220213d2073656c660000006102805261026050606461023cfd5b60e0366101a03760e061030060246339ebf82361028052610180516102a05261029c600d545afa6103fd57600080fd5b60df3d1161040a57600080fd5b61030080808080516103e05250506020810190508080805161040052505060208101905080808051610420525050602081019050808080516104405250506020810190508080805161046052505060208101905080808051610480525050602081019050808080516104a052505050506000506103e080516101a05280602001516101c05280604001516101e0528060600151610200528060800151610220528060a00151610240528060c0015161026052506101a051151561050c576308c379a06102805260206102a05260096102c0527f21617070726f76656400000000000000000000000000000000000000000000006102e0526102c050606461029cfd5b6101c051151561055b576308c379a06102805260206102a05260076102c0527f21616374697665000000000000000000000000000000000000000000000000006102e0526102c050606461029cfd5b6101e05115156105aa576308c379a06102805260206102a052600a6102c0527f21616374697661746564000000000000000000000000000000000000000000006102e0526102c050606461029cfd5b6101805161016051601481106105bf57600080fd5b600c60c052602060c0200155600b6101805160e05260c052604060c02060c052602060c020600181556001600182015560016002820155610200516003820155610220516004820155610240516005820155610260516006820155505b81516001018083528114156102fa575b50505b6001600155005b63ce5494bb811415610aff5760043560a01c1561065257600080fd5b600454331415156106a2576308c379a061014052602061016052600a610180527f2174696d65206c6f636b000000000000000000000000000000000000000000006101a05261018050606461015cfd5b60015415156106f0576308c379a061014052602061016052600c610180527f21696e697469616c697a656400000000000000000000000000000000000000006101a05261018050606461015cfd5b600054151561073e576308c379a0610140526020610160526007610180527f21706175736564000000000000000000000000000000000000000000000000006101a05261018050606461015cfd5b60035460206101a0600463fc0c546a6101405261015c6004355afa61076257600080fd5b601f3d1161076f57600080fd5b6000506101a0511415156107c2576308c379a06101c05260206101e052601f610200527f6e65772066756e64206d616e6167657220746f6b656e20213d20746f6b656e00610220526102005060646101dcfd5b60025460206101a0600463fbfa77cf6101405261015c6004355afa6107e657600080fd5b601f3d116107f357600080fd5b6000506101a051141515610846576308c379a06101c05260206101e052601f610200527f6e65772066756e64206d616e61676572207661756c7420213d207661756c7400610220526102005060646101dcfd5b61016060006014818352015b61016051600c60c052602060c0200154610140526101405115156108755761092f565b60043560206101e06004636209ec2d6101805261019c610140515afa61089a57600080fd5b601f3d116108a757600080fd5b6000506101e05114151561091f576308c379a0610200526020610220526029610240527f73747261746567792066756e64206d616e6167657220213d206e65772066756e610260527f64206d616e6167657200000000000000000000000000000000000000000000006102805261024050608461021cfd5b8151600101808352811415610852575b505060206101e060246370a0823161016052306101805261017c6003545afa61095757600080fd5b601f3d1161096457600080fd5b6000506101e05161014052610140516003546101605260043561018052610140516101a0526101a051610180516101605160065801613fe4565b610140526000506004353b6109b257600080fd5b600060006004638129fc1c6101605261017c60006004355af16109d457600080fd5b60206101e060246370a0823161016052306101805261017c6003545afa6109fa57600080fd5b601f3d11610a0757600080fd5b6000506101e051151515610a5a576308c379a0610200526020610220526008610240527f62616c20213d20300000000000000000000000000000000000000000000000006102605261024050606461021cfd5b6004356101605261014051610180526009546101a0527fd44a6dd2bfac4f6bc02d116d96aa12c24e8580626b95cb6a2f543f18cb61bd4c6060610160a1600060095561018060006014818352015b61018051600c60c052602060c020015461016052610160511515610acb57610afb565b60006004600b6101605160e05260c052604060c02060c052602060c02001555b8151600101808352811415610aa8575b5050005b6347a02a44811415610ba15760043560a01c15610b1b57600080fd5b60045433141515610b6b576308c379a061014052602061016052600a610180527f2174696d65206c6f636b000000000000000000000000000000000000000000006101a05261018050606461015cfd5b600435600555600435610140527f5c06d5a6f95a574bb95a214c88933831c63fcd6f6c5d1d61a21efb92be19bc2c6020610140a1005b631e39831e811415610c345760055433141515610bfd576308c379a061014052602061016052600f610180527f216e6578742074696d65206c6f636b00000000000000000000000000000000006101a05261018050606461015cfd5b33600455600060055533610140527f77b69635186d51fb2d031f67a7995795c8384acb800219c7d30861125d154f026020610140a1005b63704b6c02811415610d275760043560a01c15610c5057600080fd5b600454610160526006546101805260006101405261014061012060006002818352015b610120516020026101600151331415610c8f5760018352610c9f565b8151600101808352811415610c73575b505050610140511515610cf1576308c379a06101a05260206101c05260056101e0527f2161757468000000000000000000000000000000000000000000000000000000610200526101e05060646101bcfd5b600435600655600435610140527f5a272403b402d892977df56625f4164ccaf70ca3863991c43ecfe76a6905b0a16020610140a1005b638a0dac4a811415610e1a5760043560a01c15610d4357600080fd5b600454610160526006546101805260006101405261014061012060006002818352015b610120516020026101600151331415610d825760018352610d92565b8151600101808352811415610d66575b505050610140511515610de4576308c379a06101a05260206101c05260056101e0527f2161757468000000000000000000000000000000000000000000000000000000610200526101e05060646101bcfd5b600435600755600435610140527f31845eceb9cde510c7e8b37f76301c688feb70bc9653aa4c28a3734999840fd86020610140a1005b63c26f6d44811415610f0d5760043560a01c15610e3657600080fd5b600454610160526006546101805260006101405261014061012060006002818352015b610120516020026101600151331415610e755760018352610e85565b8151600101808352811415610e59575b505050610140511515610ed7576308c379a06101a05260206101c05260056101e0527f2161757468000000000000000000000000000000000000000000000000000000610200526101e05060646101bcfd5b600435600855600435610140527fcabc8521621c89fc973d8f1e8455da2ce64a666915af33e0ebaa69cd5215083b6020610140a1005b63bedb86fb8114156110075760043560011c15610f2957600080fd5b60045461016052600654610180526007546101a05260006101405261014061012060006003818352015b610120516020026101600151331415610f6f5760018352610f7f565b8151600101808352811415610f53575b505050610140511515610fd1576308c379a06101c05260206101e0526005610200527f2161757468000000000000000000000000000000000000000000000000000000610220526102005060646101dcfd5b600435600055600435610140527f140eb9f8b591138e129e4caf389c92df4f0545b902523eee9e63153ecdb2026e6020610140a1005b636817031b8114156111b05760043560a01c1561102357600080fd5b60045433141515611073576308c379a061014052602061016052600a610180527f2174696d65206c6f636b000000000000000000000000000000000000000000006101a05261018050606461015cfd5b60035460206101a0600463fc0c546a6101405261015c6004355afa61109757600080fd5b601f3d116110a457600080fd5b6000506101a0511415156110f7576308c379a06101c05260206101e0526014610200527f7661756c7420746f6b656e20213d20746f6b656e000000000000000000000000610220526102005060646101dcfd5b6000600254181561112f57600354610140526002546101605260006101805261018051610160516101405160065801613fe4565b6000505b60043560025560035461014052600254610160527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101805261018051610160516101405160065801613fe4565b600050600435610140527fd459c7242e23d490831b5676a611c4342d899d28f342d89ae80793e56a930f306020610140a1005b6301e1d1148114156111d657600658016144c9565b610140526101405160005260206000f35b633b8ae39781141561141f5760043560a01c156111f257600080fd5b60045433141515611242576308c379a061014052602061016052600a610180527f2174696d65206c6f636b000000000000000000000000000000000000000000006101a05261018050606461015cfd5b600b60043560e05260c052604060c02060c052602060c020541515156112a7576308c379a0610140526020610160526008610180527f617070726f7665640000000000000000000000000000000000000000000000006101a05261018050606461015cfd5b3060206101a06004636209ec2d6101405261015c6004355afa6112c957600080fd5b601f3d116112d657600080fd5b6000506101a051141515611329576308c379a06101c05260206101e052601d610200527f73747261746567792066756e64206d616e6167657220213d2074686973000000610220526102005060646101dcfd5b60035460206101a0600463fc0c546a6101405261015c6004355afa61134d57600080fd5b601f3d1161135a57600080fd5b6000506101a0511415156113ad576308c379a06101c05260206101e0526017610200527f737472617465677920746f6b656e20213d20746f6b656e000000000000000000610220526102005060646101dcfd5b600b60043560e05260c052604060c02060c052602060c02060018155600060018201556000600282015560006003820155600060048201556000600582015560006006820155506004357f4c6d0fbb89373829bc56000a87d561331bca06f725fd8861d055215ed90f209b60006000a2005b63bb994d488114156115ee5760043560a01c1561143b57600080fd5b600454610160526006546101805260006101405261014061012060006002818352015b61012051602002610160015133141561147a576001835261148a565b815160010180835281141561145e575b5050506101405115156114dc576308c379a06101a05260206101c05260056101e0527f2161757468000000000000000000000000000000000000000000000000000000610200526101e05060646101bcfd5b600b60043560e05260c052604060c02060c052602060c020541515611540576308c379a0610140526020610160526009610180527f21617070726f76656400000000000000000000000000000000000000000000006101a05261018050606461015cfd5b6001600b60043560e05260c052604060c02060c052602060c02001541515156115a8576308c379a0610140526020610160526006610180527f61637469766500000000000000000000000000000000000000000000000000006101a05261018050606461015cfd5b6000600b60043560e05260c052604060c02060c052602060c020556004357f7d3e35e217272b8400fec8397b08eb8c60c4db9ae834af14ac0fc9c0bb914a8f60006000a2005b635f1ac3108114156119315760043560a01c1561160a57600080fd5b600454610160526006546101805260006101405261014061012060006002818352015b6101205160200261016001513314156116495760018352611659565b815160010180835281141561162d575b5050506101405115156116ab576308c379a06101a05260206101c05260056101e0527f2161757468000000000000000000000000000000000000000000000000000000610200526101e05060646101bcfd5b600b60043560e05260c052604060c02060c052602060c02054151561170f576308c379a0610140526020610160526009610180527f21617070726f76656400000000000000000000000000000000000000000000006101a05261018050606461015cfd5b6001600b60043560e05260c052604060c02060c052602060c0200154151515611777576308c379a0610140526020610160526006610180527f61637469766500000000000000000000000000000000000000000000000000006101a05261018050606461015cfd5b612710600a5460243581818301101561178f57600080fd5b80820190509050111515156117e3576308c379a061014052602061016052600b610180527f726174696f203e206d61780000000000000000000000000000000000000000006101a05261018050606461015cfd5b60643560443511151515611836576308c379a0610140526020610160526017610180527f6d696e20626f72726f77203e206d617820626f72726f770000000000000000006101a05261018050606461015cfd5b600435610140526101405160065801614676565b60005060016001600b60043560e05260c052604060c02060c052602060c020015560016002600b60043560e05260c052604060c02060c052602060c02001556024356003600b60043560e05260c052604060c02060c052602060c02001556044356005600b60043560e05260c052604060c02060c052602060c02001556064356006600b60043560e05260c052604060c02060c052602060c0200155600a80546024358181830110156118fc57600080fd5b808201905090508155506004357fa3cbd67e6583e6c7ef034e5f87b7b40b0a0e87182a8377dfb42e59aa414c6cd560006000a2005b63b22439f5811415611b5a5760043560a01c1561194d57600080fd5b60045461016052600654610180526007546101a05260006101405261014061012060006003818352015b61012051602002610160015133141561199357600183526119a3565b8151600101808352811415611977575b5050506101405115156119f5576308c379a06101c05260206101e0526005610200527f2161757468000000000000000000000000000000000000000000000000000000610220526102005060646101dcfd5b6001600b60043560e05260c052604060c02060c052602060c02001541515611a5c576308c379a0610140526020610160526007610180527f21616374697665000000000000000000000000000000000000000000000000006101a05261018050606461015cfd5b600435610140526101405160065801614813565b6101a0526101a0516101c0526101405161016051610180516101a0516101c0516101c0516101e0526101e0516006580161470c565b6101c0526101a05261018052610160526101405260005060006001600b60043560e05260c052604060c02060c052602060c0200155600a80546003600b60043560e05260c052604060c02060c052602060c020015480821015611b0757600080fd5b8082039050905081555060006003600b60043560e05260c052604060c02060c052602060c02001556004357fff2f97c1f3529c6b02543b63f7efae22cdc885048adf65c679a1c5c4ea3b2fa860006000a2005b63c5cde90b81141561201a576000610120525b610120516004013560a01c15611b8257600080fd5b6020610120510161012052610280610120511015611b9f57611b6d565b600454610160526006546101805260006101405261014061012060006002818352015b610120516020026101600151331415611bde5760018352611bee565b8151600101808352811415611bc2575b505050610140511515611c40576308c379a06101a05260206101c05260056101e0527f2161757468000000000000000000000000000000000000000000000000000000610200526101e05060646101bcfd5b60006101405261016060006014818352015b60046101605160148110611c6557600080fd5b602002013561018052610180511515611c8e57610140511515611c89576001610140525b611cde565b61014051151515611cde576308c379a06101a05260206101c05260036101e0527f6761700000000000000000000000000000000000000000000000000000000000610200526101e05060646101bcfd5b8151600101808352811415611c52575b505061016060006014818352015b6101605160148110611d0d57600080fd5b600c60c052602060c02001546101805260046101605160148110611d3057600080fd5b60200201356101a052610180511515611d98576101a051151515611d93576308c379a06101c05260206101e0526008610200527f6e657720213d2030000000000000000000000000000000000000000000000000610220526102005060646101dcfd5b611deb565b60006101a05114151515611deb576308c379a06101c05260206101e0526007610200527f6e6577203d203000000000000000000000000000000000000000000000000000610220526102005060646101dcfd5b8151600101808352811415611cfc575b505061016060006014818352015b60046101605160148110611e1c57600080fd5b602002013561018052610180511515611e3457611ecc565b6001600b6101805160e05260c052604060c02060c052602060c02001541515611e9c576308c379a06101a05260206101c05260076101e0527f2161637469766500000000000000000000000000000000000000000000000000610200526101e05060646101bcfd5b60006001600b6101805160e05260c052604060c02060c052602060c02001555b8151600101808352811415611e09575b505061016060006014818352015b60046101605160148110611eed57600080fd5b602002013561018052610180511515611f0557611f56565b60016001600b6101805160e05260c052604060c02060c052602060c0200155610180516101605160148110611f3957600080fd5b600c60c052602060c02001555b8151600101808352811415611eda575b505060043561016052602435610180526044356101a0526064356101c0526084356101e05260a4356102005260c4356102205260e4356102405261010435610260526101243561028052610144356102a052610164356102c052610184356102e0526101a435610300526101c435610320526101e4356103405261020435610360526102243561038052610244356103a052610264356103c0527fa03ab32749bdff946d914bdbc7fadedf2bdeb6a83f2b56effa25a0eae1012675610280610160a1005b63260829c081141561233c57600454610160526006546101805260006101405261014061012060006002818352015b6101205160200261016001513314156120655760018352612075565b8151600101808352811415612049575b5050506101405115156120c7576308c379a06101a05260206101c05260056101e0527f2161757468000000000000000000000000000000000000000000000000000000610200526101e05060646101bcfd5b61014060006014818352015b61014051601481106120e457600080fd5b600c60c052602060c0200154151561215a576004610140516014811061210957600080fd5b602002013515151561215a576308c379a061016052602061018052600f6101a0527f6465627420726174696f20213d203000000000000000000000000000000000006101c0526101a050606461017cfd5b81516001018083528114156120d3575b505060006101405261016060006014818352015b610160516014811061218f57600080fd5b600c60c052602060c0200154610180526101805115156121ae5761221e565b600461016051601481106121c157600080fd5b60200201356101a0526101a0516003600b6101805160e05260c052604060c02060c052602060c020015561014080516101a05181818301101561220357600080fd5b808201905090508152505b815160010180835281141561217e575b505061014051600a55612710600a541115151561227a576308c379a061016052602061018052600b6101a0527f746f74616c203e206d61780000000000000000000000000000000000000000006101c0526101a050606461017cfd5b60043561016052602435610180526044356101a0526064356101c0526084356101e05260a4356102005260c4356102205260e4356102405261010435610260526101243561028052610144356102a052610164356102c052610184356102e0526101a435610300526101c435610320526101e4356103405261020435610360526102243561038052610244356103a052610264356103c0527f8edb07c0d6dfa3d8e47f8faaeffa94a7c21b80ebb98ccf264581f64c8270a906610280610160a1005b63da1714318114156125285760043560a01c1561235857600080fd5b600454610160526006546101805260006101405261014061012060006002818352015b61012051602002610160015133141561239757600183526123a7565b815160010180835281141561237b575b5050506101405115156123f9576308c379a06101a05260206101c05260056101e0527f2161757468000000000000000000000000000000000000000000000000000000610200526101e05060646101bcfd5b600b60043560e05260c052604060c02060c052602060c02054151561245d576308c379a0610140526020610160526009610180527f21617070726f76656400000000000000000000000000000000000000000000006101a05261018050606461015cfd5b604435602435111515156124b0576308c379a0610140526020610160526017610180527f6d696e20626f72726f77203e206d617820626f72726f770000000000000000006101a05261018050606461015cfd5b6024356005600b60043560e05260c052604060c02060c052602060c02001556044356006600b60043560e05260c052604060c02060c052602060c020015560243561014052604435610160526004357ffedf8d30e937b57e4e95271e9f17cfab1a1315ac6d612ef72912405e9524f7d56040610140a2005b63505b6a768114156126fb576001541515612582576308c379a061014052602061016052600c610180527f21696e697469616c697a656400000000000000000000000000000000000000006101a05261018050606461015cfd5b60045461016052600654610180526008546101a05260006101405261014061012060006003818352015b6101205160200261016001513314156125c857600183526125d8565b81516001018083528114156125ac575b50505061014051151561262a576308c379a06101c05260206101e0526005610200527f2161757468000000000000000000000000000000000000000000000000000000610220526102005060646101dcfd5b60206101e0602463c5ebeaec610160526004356101805261017c60006002545af161265457600080fd5b601f3d1161266157600080fd5b6000506101e0516101405260243561014051101515156126c0576308c379a061016052602061018052600e6101a0527f626f72726f776564203c206d696e0000000000000000000000000000000000006101c0526101a050606461017cfd5b6004356101605261014051610180526002547fb87de9931230544a0b3a00e753f5ab70f79a54e84e47bcad4239e1c1c97588d36040610160a2005b6348b8a1f98114156128ce576001541515612755576308c379a061014052602061016052600c610180527f21696e697469616c697a656400000000000000000000000000000000000000006101a05261018050606461015cfd5b60045461016052600654610180526008546101a05260006101405261014061012060006003818352015b61012051602002610160015133141561279b57600183526127ab565b815160010180835281141561277f575b5050506101405115156127fd576308c379a06101c05260206101e0526005610200527f2161757468000000000000000000000000000000000000000000000000000000610220526102005060646101dcfd5b60206101e0602463371fd8e6610160526004356101805261017c60006002545af161282757600080fd5b601f3d1161283457600080fd5b6000506101e051610140526024356101405110151515612893576308c379a061016052602061018052600c6101a0527f726570616964203c206d696e00000000000000000000000000000000000000006101c0526101a050606461017cfd5b6004356101605261014051610180526002547f447949f39e7c140dbba1469e2e065abd8a278ac561449a4fcd1c51f5aadc91d86040610160a2005b63d5b6e219811415612bc5576001541515612928576308c379a061014052602061016052600c610180527f21696e697469616c697a656400000000000000000000000000000000000000006101a05261018050606461015cfd5b60045461016052600654610180526008546101a05260006101405261014061012060006003818352015b61012051602002610160015133141561296e576001835261297e565b8151600101808352811415612952575b5050506101405115156129d0576308c379a06101c05260206101e0526005610200527f2161757468000000000000000000000000000000000000000000000000000000610220526102005060646101dcfd5b61014051600658016144c9565b6101605261014052610160516101405260043561014051101515612a0957602435610140511115612a0c565b60005b1515612a57576308c379a06101605260206101805260126101a0527f746f74616c206e6f7420696e2072616e676500000000000000000000000000006101c0526101a050606461017cfd5b60206101e06004630dca59c16101805261019c6002545afa612a7857600080fd5b601f3d11612a8557600080fd5b6000506101e051610160526040366101803761016051610140511115612af957610140516101605180821015612aba57600080fd5b808203905090506101405160095480821015612ad557600080fd5b8082039050905080821115612aea5780612aec565b815b9050905061018052612b1a565b610160516101405180821015612b0e57600080fd5b808203905090506101a0525b6000610180511115612b2d576001612b35565b60006101a051115b15612b79576002543b612b4757600080fd5b60006000604463753c09856101c052610180516101e0526101a051610200526101dc60006002545af1612b7957600080fd5b610140516101c052610160516101e05261018051610200526101a051610220526002547fd94ac81cdb49ea558800854e3bfd1aedf2a0a02abc471047c34e382fd5137cbd60806101c0a2005b632e1a7d4d811415612f1e576001541515612c1f576308c379a061014052602061016052600c610180527f21696e697469616c697a656400000000000000000000000000000000000000006101a05261018050606461015cfd5b60025433141515612c6f576308c379a0610140526020610160526006610180527f217661756c7400000000000000000000000000000000000000000000000000006101a05261018050606461015cfd5b61014051600658016144c9565b610160526101405261016051610140526004356101405180821115612ca15780612ca3565b815b9050905061016052600061016051111515612cfd576308c379a06101805260206101a052600c6101c0527f7769746864726177203d203000000000000000000000000000000000000000006101e0526101c050606461019cfd5b60206102006004630dca59c16101a0526101bc6002545afa612d1e57600080fd5b601f3d11612d2b57600080fd5b600050610200516101805260006101a05261014051610180511115612d6b57610180516101405180821015612d5f57600080fd5b808203905090506101a0525b602061026060246370a082316101e05230610200526101fc6003545afa612d9157600080fd5b601f3d11612d9e57600080fd5b600050610260516101c0526101c051610160511115612e71576101a080516101405161016051610180516101a0516101c051610160516101e0526101e051600658016148b7565b610240526101c0526101a05261018052610160526101405261024051818183011015612e1057600080fd5b8082019050905081525061016051602061026060246370a082316101e05230610200526101fc6003545afa612e4457600080fd5b601f3d11612e5157600080fd5b6000506102605180821115612e665780612e68565b815b90509050610160525b6000610160511115612ed2576101405161016051610180516101a0516101c0516003546101e0523361020052610160516102205261022051610200516101e0516006580161417e565b6101c0526101a0526101805261016052610140526000505b6004356101e05261016051610200526101a05161022052337f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca9460606101e0a26101a05160005260206000f35b63f19f0542811415612f5f5760043560a01c15612f3a57600080fd5b600435610140526101405160065801614bbd565b6101a0526101a05160005260206000f35b63c6f2be58811415612fa05760043560a01c15612f7b57600080fd5b600435610140526101405160065801614d9d565b6101a0526101a05160005260206000f35b639a78e72e811415612fe15760043560a01c15612fbc57600080fd5b6004600b60043560e05260c052604060c02060c052602060c020015460005260206000f35b63c5ebeaec81141561326657600e5415612ffa57600080fd5b6001600e55600154151561304d576308c379a061014052602061016052600c610180527f21696e697469616c697a656400000000000000000000000000000000000000006101a05261018050606461015cfd5b60005415151561309c576308c379a0610140526020610160526006610180527f70617573656400000000000000000000000000000000000000000000000000006101a05261018050606461015cfd5b6001600b3360e05260c052604060c02060c052602060c02001541515613101576308c379a0610140526020610160526007610180527f21616374697665000000000000000000000000000000000000000000000000006101a05261018050606461015cfd5b6004356101405133610160526101605160065801614bbd565b6101c052610140526101c051808211156131345780613136565b815b9050905061014052600061014051111515613190576308c379a061016052602061018052600a6101a0527f626f72726f77203d2030000000000000000000000000000000000000000000006101c0526101a050606461017cfd5b61014051600354610160523361018052610140516101a0526101a05161018051610160516006580161417e565b610140526000506004600b3360e05260c052604060c02060c052602060c020018054610140518181830110156131f257600080fd5b80820190509050815550600980546101405181818301101561321357600080fd5b80820190509050815550600435610160526101405161018052337fe1979fe4c35e0cef342fef5668e2c8e7a7e9f5d5d1ca8fee0ac6c427fa4153af6040610160a2610140516000526000600e5560206000f35b63371fd8e681141561351b5760015415156132c0576308c379a061014052602061016052600c610180527f21696e697469616c697a656400000000000000000000000000000000000000006101a05261018050606461015cfd5b600b3360e05260c052604060c02060c052602060c020541515613322576308c379a0610140526020610160526009610180527f21617070726f76656400000000000000000000000000000000000000000000006101a05261018050606461015cfd5b6004356004600b3360e05260c052604060c02060c052602060c02001548082111561334d578061334f565b815b90509050610140526000610140511115156133a9576308c379a06101605260206101805260096101a0527f7265706179203d203000000000000000000000000000000000000000000000006101c0526101a050606461017cfd5b602061020060246370a0823161018052306101a05261019c6003545afa6133cf57600080fd5b601f3d116133dc57600080fd5b6000506102005161016052610140516101605160035461018052336101a052306101c052610140516101e0526101e0516101c0516101a0516101805160065801614318565b6101605261014052600050602061020060246370a0823161018052306101a05261019c6003545afa61345257600080fd5b601f3d1161345f57600080fd5b60005061020051610160518082101561347757600080fd5b80820390509050610160526004600b3360e05260c052604060c02060c052602060c02001805461016051808210156134ae57600080fd5b808203905090508155506009805461016051808210156134cd57600080fd5b8082039050905081555060043561018052610160516101a052337f77c6871227e5d2dec8dadd5354f78453203e22e669cd0ec4c19d9a8c5edb31d06040610180a26101605160005260206000f35b63753c0985811415613754576001541515613575576308c379a061014052602061016052600c610180527f21696e697469616c697a656400000000000000000000000000000000000000006101a05261018050606461015cfd5b6001600b3360e05260c052604060c02060c052602060c020015415156135da576308c379a0610140526020610160526007610180527f21616374697665000000000000000000000000000000000000000000000000006101a05261018050606461015cfd5b60006004351015156135ef57602435156135f2565b60005b156135fe576001613616565b60043515156136135760006024351015613616565b60005b1515613661576308c379a0610140526020610160526011610180527f6761696e20616e64206c6f7373203e20300000000000000000000000000000006101a05261018050606461015cfd5b600060043511156136a55760035461014052336101605230610180526004356101a0526101a05161018051610160516101405160065801614318565b600050613704565b60006024351115613704576004600b3360e05260c052604060c02060c052602060c020018054602435808210156136db57600080fd5b8082039050905081555060098054602435808210156136f957600080fd5b808203905090508155505b60406004610140376004600b3360e05260c052604060c02060c052602060c020015461018052337f36d8646df39e8831ab3926651692b6a0ea874e6cc807ea1c428fcf2ba32859f86060610140a2005b636cb56d19811415613bf85760043560a01c1561377057600080fd5b60243560a01c1561378057600080fd5b60015415156137ce576308c379a061014052602061016052600c610180527f21696e697469616c697a656400000000000000000000000000000000000000006101a05261018050606461015cfd5b600454610160526006546101805260006101405261014061012060006002818352015b61012051602002610160015133141561380d576001835261381d565b81516001018083528114156137f1575b50505061014051151561386f576308c379a06101a05260206101c05260056101e0527f2161757468000000000000000000000000000000000000000000000000000000610200526101e05060646101bcfd5b6001600b60043560e05260c052604060c02060c052602060c020015415156138d6576308c379a061014052602061016052600b610180527f6f6c6420216163746976650000000000000000000000000000000000000000006101a05261018050606461015cfd5b600b60243560e05260c052604060c02060c052602060c02054151561393a576308c379a061014052602061016052600d610180527f6e65772021617070726f766564000000000000000000000000000000000000006101a05261018050606461015cfd5b6002600b60243560e05260c052604060c02060c052602060c02001541515156139a2576308c379a0610140526020610160526009610180527f61637469766174656400000000000000000000000000000000000000000000006101a05261018050606461015cfd5b610140600b60043560e05260c052604060c0208060c052602060c02054825260018160c052602060c0200154826020015260028160c052602060c0200154826040015260038160c052602060c0200154826060015260048160c052602060c0200154826080015260058160c052602060c02001548260a0015260068160c052602060c02001548260c001525050600b60243560e05260c052604060c02060c052602060c0206001815560016001820155600160028201556101a05160038201556101c05160048201556101e05160058201556102005160068201555060006001600b60043560e05260c052604060c02060c052602060c020015560006003600b60043560e05260c052604060c02060c052602060c020015560006004600b60043560e05260c052604060c02060c052602060c020015560006005600b60043560e05260c052604060c02060c052602060c020015560006006600b60043560e05260c052604060c02060c052602060c02001556101405161016051610180516101a0516101c0516101e0516102005161022051600435610240526102405160065801614813565b6102a05261022052610200526101e0526101c0526101a0526101805261016052610140526102a051610220526024356102205160148110613b8857600080fd5b600c60c052602060c02001556004353b613ba157600080fd5b60006000602463ce5494bb610240526024356102605261025c60006004355af1613bca57600080fd5b6024356004357f9249d6a64288c19c5be5f4f1bb9b763ad4afac803128f1ef65b88acb13df9aa460006000a3005b6301681a62811415613da45760043560a01c15613c1457600080fd5b600454610160526006546101805260006101405261014061012060006002818352015b610120516020026101600151331415613c535760018352613c63565b8151600101808352811415613c37575b505050610140511515613cb5576308c379a06101a05260206101c05260056101e0527f2161757468000000000000000000000000000000000000000000000000000000610200526101e05060646101bcfd5b60035460043514151515613d08576308c379a0610140526020610160526009610180527f70726f74656374656400000000000000000000000000000000000000000000006101a05261018050606461015cfd5b60206101c060246370a0823161014052306101605261015c6004355afa613d2e57600080fd5b601f3d11613d3b57600080fd5b6000506101c0516101e0526101405161016051610180516101a0516101c0516101e0516004356102005233610220526101e051610240526102405161022051610200516006580161417e565b6101e0526101c0526101a052610180526101605261014052600050005b635c975abb811415613dbc5760005460005260206000f35b63158ef93e811415613dd45760015460005260206000f35b63fbfa77cf811415613dec5760025460005260206000f35b63fc0c546a811415613e045760035460005260206000f35b63d085835a811415613e1c5760045460005260206000f35b63b127df87811415613e345760055460005260206000f35b63f851a440811415613e4c5760065460005260206000f35b63452a9320811415613e645760075460005260206000f35b634d547ada811415613e7c5760085460005260206000f35b63fc7b9c18811415613e945760095460005260206000f35b632df9eab9811415613eac57600a5460005260206000f35b6339ebf823811415613f935760043560a01c15613ec857600080fd5b600b60043560e05260c052604060c0206101408080808460c052602060c0205481525050602081019050808060018560c052602060c020015481525050602081019050808060028560c052602060c020015481525050602081019050808060038560c052602060c020015481525050602081019050808060048560c052602060c020015481525050602081019050808060058560c052602060c020015481525050602081019050808060068560c052602060c02001548152505060e09050905060c05260c051610140f35b63ddf0b009811415613fc45760043560148110613faf57600080fd5b600c60c052602060c020015460005260206000f35b63a598adff811415613fdc57600d5460005260206000f35b505b60006000fd5b6101a05261014052610160526101805260006004610220527f095ea7b3000000000000000000000000000000000000000000000000000000006102405261022060048060208461028001018260208501600060045af15050805182019150506101605160208261028001015260208101905061018051602082610280010152602081019050806102805261028090508051602001806103208284600060045af161408d57600080fd5b505060206103e0610320516103406000610140515af16140ac57600080fd5b60203d808211156140bd57806140bf565b815b905090506103c0526103c08051602001806101c08284600060045af16140e457600080fd5b505060006101c0511115614178576101c080602001516000825180602090131561410d57600080fd5b809190121561411b57600080fd5b806020036101000a820490509050905015151515614178576308c379a061022052602061024052600e610260527f617070726f7665206661696c65640000000000000000000000000000000000006102805261026050606461023cfd5b6101a051565b6101a05261014052610160526101805260006004610220527fa9059cbb000000000000000000000000000000000000000000000000000000006102405261022060048060208461028001018260208501600060045af15050805182019150506101605160208261028001015260208101905061018051602082610280010152602081019050806102805261028090508051602001806103208284600060045af161422757600080fd5b505060206103e0610320516103406000610140515af161424657600080fd5b60203d808211156142575780614259565b815b905090506103c0526103c08051602001806101c08284600060045af161427e57600080fd5b505060006101c0511115614312576101c08060200151600082518060209013156142a757600080fd5b80919012156142b557600080fd5b806020036101000a820490509050905015151515614312576308c379a061022052602061024052600f610260527f7472616e73666572206661696c656400000000000000000000000000000000006102805261026050606461023cfd5b6101a051565b6101c0526101405261016052610180526101a05260006004610240527f23b872dd00000000000000000000000000000000000000000000000000000000610260526102406004806020846102a001018260208501600060045af1505080518201915050610160516020826102a0010152602081019050610180516020826102a00101526020810190506101a0516020826102a0010152602081019050806102a0526102a090508051602001806103608284600060045af16143d857600080fd5b50506020610440610360516103806000610140515af16143f757600080fd5b60203d80821115614408578061440a565b815b90509050610420526104208051602001806101e08284600060045af161442f57600080fd5b505060006101e05111156144c3576101e080602001516000825180602090131561445857600080fd5b809190121561446657600080fd5b806020036101000a8204905090509050151515156144c3576308c379a0610240526020610260526013610280527f7472616e7366657246726f6d206661696c6564000000000000000000000000006102a05261028050606461025cfd5b6101c051565b6101405260206101e060246370a0823161016052306101805261017c6003545afa6144f357600080fd5b601f3d1161450057600080fd5b6000506101e05160095481818301101561451957600080fd5b8082019050905060005260005161014051565b610140526102a0366101603761042060006014818352015b61042051600c60c052602060c02001546104005260006104005118156145a257610400516101606103e0516014811061457c57600080fd5b60200201526103e08051600181818301101561459757600080fd5b808201905090508152505b8151600101808352811415614544575b5050600c60c052602060c0206101605181556101805160018201556101a05160028201556101c05160038201556101e05160048201556102005160058201556102205160068201556102405160078201556102605160088201556102805160098201556102a051600a8201556102c051600b8201556102e051600c82015561030051600d82015561032051600e82015561034051600f8201556103605160108201556103805160118201556103a05160128201556103c05160138201555061014051565b61016052610140526013600c60c052602060c02001541515156146d8576308c379a06101805260206101a052600b6101c0527f7175657565203e206d61780000000000000000000000000000000000000000006101e0526101c050606461019cfd5b610140516013600c60c052602060c020015561014051610160516006580161452c565b610160526101405260005061016051565b6101605261014052601461014051101515614766576308c379a06101805260206101a05260086101c0527f69203e3d206d61780000000000000000000000000000000000000000000000006101e0526101c050606461019cfd5b6000610140516014811061477957600080fd5b600c60c052602060c0200154141515156147d2576308c379a06101805260206101a052600d6101c0527f217a65726f2061646472657373000000000000000000000000000000000000006101e0526101c050606461019cfd5b600061014051601481106147e557600080fd5b600c60c052602060c020015561014051610160516006580161452c565b610160526101405260005061016051565b610160526101405261018060006014818352015b61014051610180516014811061483c57600080fd5b600c60c052602060c020015414156148605761018051600052505060005161016051565b8151600101808352811415614827575b50506308c379a06101805260206101a05260096101c0527f6e6f7420666f756e6400000000000000000000000000000000000000000000006101e0526101c050606461019cfd5b6101605261014052610140516101805260006101a0526101e060006014818352015b6101e051600c60c052602060c02001546101c0526101c05115156148fc57614bab565b60206102a060246370a0823161022052306102405261023c6003545afa61492257600080fd5b601f3d1161492f57600080fd5b6000506102a05161020052610180516102005110151561494e57614bab565b6004600b6101c05160e05260c052604060c02060c052602060c02001546102205261018051610200518082101561498457600080fd5b80820390509050610220518082111561499d578061499f565b815b90509050610240526102405115156149b657614b9b565b60206103006024632e1a7d4d61028052610240516102a05261029c60006101c0515af16149e257600080fd5b601f3d116149ef57600080fd5b6000506103005161026052602061032060246370a082316102a052306102c0526102bc6003545afa614a2057600080fd5b601f3d11614a2d57600080fd5b600050610320516102005180821015614a4557600080fd5b80820390509050610280526000610260511115614af75761018080516102605180821015614a7257600080fd5b808203905090508152506101a0805161026051818183011015614a9457600080fd5b808201905090508152506004600b6101c05160e05260c052604060c02060c052602060c0200180546102605180821015614acd57600080fd5b80820390509050815550600980546102605180821015614aec57600080fd5b808203905090508155505b6004600b6101c05160e05260c052604060c02060c052602060c0200180546102805180821015614b2657600080fd5b80820390509050815550600980546102805180821015614b4557600080fd5b80820390509050815550610220516102a052610240516102c052610260516102e05261028051610300526101c0517fa1db2d4488a8004dde12ff73253859b508b0458878ea4086047bab6672f9f1d760806102a0a25b81516001018083528114156148d9575b50506101a05160005260005161016051565b61016052610140526001541515614bd5576001614be9565b60005415614be4576001614be9565b600a54155b15614bfc57600060005260005161016051565b6003600b6101405160e05260c052604060c02060c052602060c0200154610140516101605161018051600658016144c9565b6101a0526101805261016052610140526101a0518082028215828483041417614c5657600080fd5b80905090509050600a548080614c6b57600080fd5b820490509050610180526004600b6101405160e05260c052604060c02060c052602060c02001546101a052610180516101a051101515614cb357600060005260005161016051565b610180516101a05180821015614cc857600080fd5b80820390509050602061026060246370a082316101e05230610200526101fc6003545afa614cf557600080fd5b601f3d11614d0257600080fd5b6000506102605180821115614d175780614d19565b815b905090506101c0526005600b6101405160e05260c052604060c02060c052602060c02001546101c0511015614d5a5760006000526000516101605156614d9b565b6101c0516006600b6101405160e05260c052604060c02060c052602060c020015480821115614d895780614d8b565b815b9050905060005260005161016051565b005b61016052610140526001541515614dbc57600060005260005161016051565b600a541515614dee576004600b6101405160e05260c052604060c02060c052602060c020015460005260005161016051565b6003600b6101405160e05260c052604060c02060c052602060c02001546009548082028215828483041417614e2257600080fd5b80905090509050600a548080614e3757600080fd5b820490509050610180526004600b6101405160e05260c052604060c02060c052602060c02001546101a05260005415614e7e576101a0516000526000516101605156614ec7565b610180516101a051111515614e9f5760006000526000516101605156614ec7565b6101a0516101805180821015614eb457600080fd5b8082039050905060005260005161016051565b00
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.