More Info
Private Name Tags
ContractCreator
TokenTracker
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
DharmaDaiPrototype1
Compiler Version
v0.5.11+commit.c082d0b4
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-01-14 */ pragma solidity 0.5.11; // optimization runs: 200, evm version: petersburg interface DTokenInterface { // Events (replicate Compound's events) event Mint(address minter, uint256 mintAmount, uint256 mintTokens); event Redeem(address redeemer, uint256 redeemAmount, uint256 redeemTokens); // external functions (trigger accrual) function mint(uint256 underlyingToSupply) external returns (uint256 dTokensMinted); function mintViaCToken(uint256 cTokensToSupply) external returns (uint256 dTokensMinted); function redeem(uint256 dTokensToBurn) external returns (uint256 underlyingReceived); function redeemToCToken(uint256 dTokensToBurn) external returns (uint256 cTokensReceived); function redeemUnderlying(uint256 underelyingToReceive) external returns (uint256 dTokensBurned); function redeemUnderlyingToCToken(uint256 underlyingToReceive) external returns (uint256 dTokensBurned); function transferUnderlying(address recipient, uint256 amount) external returns (bool); function transferUnderlyingFrom(address sender, address recipient, uint256 amount) external returns (bool); function pullSurplus() external returns (uint256 cTokenSurplus); function accrueInterest() external; // view functions (do not trigger accrual) function totalSupplyUnderlying() external view returns (uint256); function balanceOfUnderlying(address account) external view returns (uint256 underlyingBalance); function getSurplus() external view returns (uint256 cTokenSurplus); function getSurplusUnderlying() external view returns (uint256 underlyingSurplus); function exchangeRateCurrent() external view returns (uint256 dTokenExchangeRate); function supplyRatePerBlock() external view returns (uint256 dTokenInterestRate); function getSpreadPerBlock() external view returns (uint256 rateSpread); function getVersion() external pure returns (uint256 version); } interface CTokenInterface { function mint(uint256 mintAmount) external returns (uint256 err); function redeem(uint256 redeemAmount) external returns (uint256 err); function redeemUnderlying(uint256 redeemAmount) external returns (uint256 err); function balanceOf(address account) external view returns (uint256 balance); function balanceOfUnderlying(address account) external returns (uint256 balance); function exchangeRateCurrent() external returns (uint256 exchangeRate); function transfer(address recipient, uint256 value) external returns (bool); function transferFrom(address sender, address recipient, uint256 value) external returns (bool); function supplyRatePerBlock() external view returns (uint256 rate); function exchangeRateStored() external view returns (uint256 rate); function accrualBlockNumber() external view returns (uint256 blockNumber); } interface ERC20Interface { event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); function transfer(address recipient, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); } interface SpreadRegistryInterface { function getDaiSpreadPerBlock() external view returns (uint256 daiSpreadPerBlock); } library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); uint256 c = a - b; return c; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); uint256 c = a / b; return c; } } /** * @title DharmaDaiPrototype1 * @author 0age (dToken mechanics derived from Compound cTokens, ERC20 methods * derived from Open Zeppelin's ERC20 contract) * @notice Initial prototype for a cDai wrapper token. This version is not * upgradeable, and serves as an initial test of the eventual dDai mechanics. * The dDai exchange rate will grow at the rate of the cDai exchange rate less * the Dai spread set on the Dharma Spread Registry. */ contract DharmaDaiPrototype1 is ERC20Interface, DTokenInterface { using SafeMath for uint256; uint256 internal constant _DHARMA_DAI_VERSION = 0; string internal constant _NAME = "Dharma Dai (Prototype 1)"; string internal constant _SYMBOL = "dDai-p1"; uint8 internal constant _DECIMALS = 8; // to match cDai uint256 internal constant _SCALING_FACTOR = 1e18; uint256 internal constant _HALF_OF_SCALING_FACTOR = 5e17; uint256 internal constant _COMPOUND_SUCCESS = 0; CTokenInterface internal constant _CDAI = CTokenInterface( 0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643 // mainnet ); ERC20Interface internal constant _DAI = ERC20Interface( 0x6B175474E89094C44Da98b954EedeAC495271d0F // mainnet ); SpreadRegistryInterface internal constant _SPREAD = SpreadRegistryInterface( 0xA143fD004B3c26f8FAeDeb9224eC03585e63d041 ); // Note: this is just an EOA for the initial prototype. address internal constant _VAULT = 0x7e4A8391C728fEd9069B2962699AB416628B19Fa; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; // TODO: pack these more tightly in storage uint256 private _blockLastUpdated; uint256 private _dDaiExchangeRate; uint256 private _cDaiExchangeRate; constructor() public { // Approve cDai to transfer Dai on behalf of this contract in order to mint. require(_DAI.approve(address(_CDAI), uint256(-1))); _blockLastUpdated = block.number; _dDaiExchangeRate = 1e28; // 1 Dai == 1 dDai to start _cDaiExchangeRate = _CDAI.exchangeRateCurrent(); } /** * @notice Transfer `amount` Dai from `msg.sender` to this contract, use them * to mint cDAI, and mint dTokens with `msg.sender` as the beneficiary. Ensure * that this contract has been approved to transfer the Dai on behalf of the * caller. * @param daiToSupply uint256 The amount of Dai to provide as part of minting. * @return The amount of dDai received in return for the supplied Dai. */ function mint( uint256 daiToSupply ) external accrues returns (uint256 dDaiMinted) { // Pull in Dai - ensure that this contract has sufficient allowance. require( _DAI.transferFrom(msg.sender, address(this), daiToSupply), "Dai transfer failed." ); // Use the cDai to mint Dai and ensure that the operation succeeds. (bool ok, bytes memory data) = address(_CDAI).call(abi.encodeWithSelector( _CDAI.mint.selector, daiToSupply )); _checkCompoundInteraction(_CDAI.mint.selector, ok, data); // Determine the dDai to mint using the exchange rate. dDaiMinted = (daiToSupply.mul(_SCALING_FACTOR)).div(_dDaiExchangeRate); // Mint dDai to the caller. _mint(msg.sender, daiToSupply, dDaiMinted); } /** * @notice Transfer `amount` cDai from `msg.sender` to this contract and mint * dTokens with `msg.sender` as the beneficiary. Ensure that this contract has * been approved to transfer the cDai on behalf of the caller. * @param cDaiToSupply uint256 The amount of cDai to provide as part of * minting. * @return The amount of dDai received in return for the supplied cDai. */ function mintViaCToken( uint256 cDaiToSupply ) external accrues returns (uint256 dDaiMinted) { // Pull in cDai - ensure that this contract has sufficient allowance. (bool ok, bytes memory data) = address(_CDAI).call(abi.encodeWithSelector( _CDAI.transferFrom.selector, msg.sender, address(this), cDaiToSupply )); _checkCompoundInteraction(_CDAI.transferFrom.selector, ok, data); // Determine the Dai equivalent of the supplied cDai amount. uint256 daiEquivalent = cDaiToSupply.mul(_cDaiExchangeRate) / _SCALING_FACTOR; // Determine the dDai to mint using the exchange rate. dDaiMinted = (daiEquivalent.mul(_SCALING_FACTOR)).div(_dDaiExchangeRate); // Mint dDai to the caller. _mint(msg.sender, daiEquivalent, dDaiMinted); } /** * @notice Redeem `dDaiToBurn` dDai from `msg.sender`, use the corresponding * cDai to redeem Dai, and transfer the Dai to `msg.sender`. * @param dDaiToBurn uint256 The amount of dDai to provide for Dai. * @return The amount of Dai received in return for the provided cDai. */ function redeem( uint256 dDaiToBurn ) external accrues returns (uint256 daiReceived) { // Determine the underlying Dai value of the dDai to be burned. daiReceived = dDaiToBurn.mul(_dDaiExchangeRate) / _SCALING_FACTOR; // Burn the dDai. _burn(msg.sender, daiReceived, dDaiToBurn); // Use the cDai to redeem Dai and ensure that the operation succeeds. (bool ok, bytes memory data) = address(_CDAI).call(abi.encodeWithSelector( _CDAI.redeemUnderlying.selector, daiReceived )); _checkCompoundInteraction(_CDAI.redeemUnderlying.selector, ok, data); // Send the Dai to the redeemer. require(_DAI.transfer(msg.sender, daiReceived), "Dai transfer failed."); } /** * @notice Redeem `dDaiToBurn` dDai from `msg.sender` and transfer the * corresponding amount of cDai to `msg.sender`. * @param dDaiToBurn uint256 The amount of dDai to provide for Dai. * @return The amount of cDai received in return for the provided dDai. */ function redeemToCToken( uint256 dDaiToBurn ) external accrues returns (uint256 cDaiReceived) { // Determine the underlying Dai value of the dDai to be burned. uint256 daiEquivalent = dDaiToBurn.mul(_dDaiExchangeRate) / _SCALING_FACTOR; // Determine the amount of cDai corresponding to the redeemed Dai value. cDaiReceived = (daiEquivalent.mul(_SCALING_FACTOR)).div(_cDaiExchangeRate); // Burn the dDai. _burn(msg.sender, daiEquivalent, dDaiToBurn); // Transfer the cDai to the caller and ensure that the operation succeeds. (bool ok, bytes memory data) = address(_CDAI).call(abi.encodeWithSelector( _CDAI.transfer.selector, msg.sender, cDaiReceived )); _checkCompoundInteraction(_CDAI.transfer.selector, ok, data); } /** * @notice Redeem the dDai equivalent value of Dai amount `daiToReceive` from * `msg.sender`, use the corresponding cDai to redeem Dai, and transfer the * Dai to `msg.sender`. * @param daiToReceive uint256 The amount, denominated in Dai, of the cDai to * provide for Dai. * @return The amount of dDai burned in exchange for the returned Dai. */ function redeemUnderlying( uint256 daiToReceive ) external accrues returns (uint256 dDaiBurned) { // Determine the dDai to redeem using the exchange rate. dDaiBurned = (daiToReceive.mul(_SCALING_FACTOR)).div(_dDaiExchangeRate); // Burn the dDai. _burn(msg.sender, daiToReceive, dDaiBurned); // Use the cDai to redeem Dai and ensure that the operation succeeds. (bool ok, bytes memory data) = address(_CDAI).call(abi.encodeWithSelector( _CDAI.redeemUnderlying.selector, daiToReceive )); _checkCompoundInteraction(_CDAI.redeemUnderlying.selector, ok, data); // Send the Dai to the redeemer. require(_DAI.transfer(msg.sender, daiToReceive), "Dai transfer failed."); } /** * @notice Redeem the dDai equivalent value of Dai amount `daiToReceive` from * `msg.sender` and transfer the corresponding amount of cDai to `msg.sender`. * @param daiToReceive uint256 The amount, denominated in Dai, of the cDai to * provide for Dai. * @return The amount of dDai burned in exchange for the returned cDai. */ function redeemUnderlyingToCToken( uint256 daiToReceive ) external accrues returns (uint256 dDaiBurned) { // Determine the dDai to redeem using the exchange rate. dDaiBurned = (daiToReceive.mul(_SCALING_FACTOR)).div(_dDaiExchangeRate); // Burn the dDai. _burn(msg.sender, daiToReceive, dDaiBurned); // Determine the amount of cDai corresponding to the redeemed Dai value. uint256 cDaiToReceive = daiToReceive.mul(_SCALING_FACTOR).div(_cDaiExchangeRate); // Transfer the cDai to the caller and ensure that the operation succeeds. (bool ok, bytes memory data) = address(_CDAI).call(abi.encodeWithSelector( _CDAI.transfer.selector, msg.sender, cDaiToReceive )); _checkCompoundInteraction(_CDAI.transfer.selector, ok, data); } /** * @notice Transfer cDai in excess of the total dDai balance to a dedicated * "vault" account. * @return The amount of cDai transferred to the vault account. */ function pullSurplus() external accrues returns (uint256 cDaiSurplus) { // Determine the cDai surplus (difference between total dDai and total cDai) (, cDaiSurplus) = _getSurplus(); // Transfer the cDai to the vault and ensure that the operation succeeds. (bool ok, bytes memory data) = address(_CDAI).call(abi.encodeWithSelector( _CDAI.transfer.selector, _VAULT, cDaiSurplus )); _checkCompoundInteraction(_CDAI.transfer.selector, ok, data); } /** * @notice Manually advance the dDai exchange rate and update the cDai * exchange rate to that of the current block. */ function accrueInterest() external accrues { // The `accrues()` modifier contains all function logic. } /** * @notice Transfer `amount` tokens from `msg.sender` to `recipient`. * @param recipient address The account to transfer tokens to. * @param amount uint256 The amount of tokens to transfer. * @return A boolean indicating whether the transfer was successful. */ function transfer(address recipient, uint256 amount) external returns (bool) { _transfer(msg.sender, recipient, amount); return true; } /** * @notice Transfer dDai equal to `amount` Dai from `msg.sender` to = * `recipient`. * @param recipient address The account to transfer tokens to. * @param amount uint256 The amount of tokens to transfer. * @return A boolean indicating whether the transfer was successful. */ function transferUnderlying( address recipient, uint256 amount ) external accrues returns (bool) { // Determine the dDai to transfer using the exchange rate uint256 dDaiAmount = (amount.mul(_SCALING_FACTOR)).div(_dDaiExchangeRate); _transfer(msg.sender, recipient, dDaiAmount); return true; } /** * @notice Approve `spender` to transfer up to `value` tokens on behalf of * `msg.sender`. * @param spender address The account to grant the allowance. * @param value uint256 The size of the allowance to grant. * @return A boolean indicating whether the approval was successful. */ function approve(address spender, uint256 value) external returns (bool) { _approve(msg.sender, spender, value); return true; } /** * @notice Transfer `amount` tokens from `sender` to `recipient` as long as * `msg.sender` has sufficient allowance. * @param sender address The account to transfer tokens from. * @param recipient address The account to transfer tokens to. * @param amount uint256 The amount of tokens to transfer. * @return A boolean indicating whether the transfer was successful. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool) { _transfer(sender, recipient, amount); uint256 allowance = _allowances[sender][msg.sender]; if (allowance != uint256(-1)) { _approve(sender, msg.sender, allowance.sub(amount)); } return true; } /** * @notice Transfer dDai equal to `amount` Dai from `sender` to `recipient` as * long as `msg.sender` has sufficient allowance. * @param sender address The account to transfer tokens from. * @param recipient address The account to transfer tokens to. * @param amount uint256 The amount of tokens to transfer. * @return A boolean indicating whether the transfer was successful. */ function transferUnderlyingFrom( address sender, address recipient, uint256 amount ) external accrues returns (bool) { // Determine the dDai to transfer using the exchange rate uint256 dDaiAmount = (amount.mul(_SCALING_FACTOR)).div(_dDaiExchangeRate); _transfer(sender, recipient, dDaiAmount); uint256 allowance = _allowances[sender][msg.sender]; if (allowance != uint256(-1)) { _approve(sender, msg.sender, allowance.sub(dDaiAmount)); } return true; } /** * @notice Increase the current allowance of `spender` by `value` tokens. * @param spender address The account to grant the additional allowance. * @param addedValue uint256 The amount to increase the allowance by. * @return A boolean indicating whether the modification was successful. */ function increaseAllowance( address spender, uint256 addedValue ) external returns (bool) { _approve( msg.sender, spender, _allowances[msg.sender][spender].add(addedValue) ); return true; } /** * @notice Decrease the current allowance of `spender` by `value` tokens. * @param spender address The account to decrease the allowance for. * @param subtractedValue uint256 The amount to subtract from the allowance. * @return A boolean indicating whether the modification was successful. */ function decreaseAllowance( address spender, uint256 subtractedValue ) external returns (bool) { _approve( msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue) ); return true; } /** * @notice View function to get the total surplus, or cDai balance that * exceeds the total dDai balance. * @return The total surplus in cDai. */ function getSurplus() external view returns (uint256 cDaiSurplus) { // Determine the Dai surplus (difference between total dDai and total Dai) (, cDaiSurplus) = _getSurplus(); } /** * @notice View function to get the total surplus, or Dai equivalent of the * cDai balance that exceeds the total dDai balance. * @return The total surplus in Dai. */ function getSurplusUnderlying() external view returns (uint256 daiSurplus) { // Determine the Dai surplus (difference between total dDai and total Dai) (daiSurplus, ) = _getSurplus(); } /** * @notice View function to get the block number where interest was last * accrued. * @return The block number where interest was last accrued. */ function accrualBlockNumber() external view returns (uint256 blockNumber) { blockNumber = _blockLastUpdated; } /** * @notice View function to get the current dDai exchange rate (multiplied by * 10^18). * @return The current exchange rate. */ function exchangeRateCurrent() external view returns (uint256 dDaiExchangeRate) { // Get most recent dDai exchange rate by determining accrued interest (dDaiExchangeRate,,) = _getAccruedInterest(); } /** * @notice View function to get the current dDai interest earned per block * (multiplied by 10^18). * @return The current interest rate. */ function supplyRatePerBlock() external view returns (uint256 dDaiInterestRate) { (dDaiInterestRate,) = _getRatePerBlock(); } /** * @notice View function to get the current cDai interest spread over dDai per * block (multiplied by 10^18). * @return The current interest rate spread. */ function getSpreadPerBlock() external view returns (uint256 rateSpread) { (uint256 dDaiInterestRate, uint256 cDaiInterestRate) = _getRatePerBlock(); rateSpread = cDaiInterestRate - dDaiInterestRate; } /** * @notice View function to get the total dDai supply. * @return The total supply. */ function totalSupply() external view returns (uint256) { return _totalSupply; } /** * @notice View function to get the total dDai supply, denominated in Dai. * @return The total supply. */ function totalSupplyUnderlying() external view returns (uint256) { (uint256 dDaiExchangeRate,,) = _getAccruedInterest(); // Determine the total value of all issued dDai in Dai return _totalSupply.mul(dDaiExchangeRate) / _SCALING_FACTOR; } /** * @notice View function to get the total dDai balance of an account. * @param account address The account to check the dDai balance for. * @return The balance of the given account. */ function balanceOf(address account) external view returns (uint256 dDai) { dDai = _balances[account]; } /** * @notice View function to get the dDai balance of an account, denominated in * its Dai equivalent value. * @param account address The account to check the balance for. * @return The total Dai-equivalent cDai balance. */ function balanceOfUnderlying( address account ) external view returns (uint256 daiBalance) { // Get most recent dDai exchange rate by determining accrued interest (uint256 dDaiExchangeRate,,) = _getAccruedInterest(); // Convert account balance to Dai equivalent using the exchange rate daiBalance = _balances[account].mul(dDaiExchangeRate) / _SCALING_FACTOR; } /** * @notice View function to get the total allowance that `spender` has to * transfer funds from the `owner` account using `transferFrom`. * @param owner address The account that is granting the allowance. * @param spender address The account that has been granted the allowance. * @return The allowance of the given spender for the given owner. */ function allowance(address owner, address spender) external view returns (uint256) { return _allowances[owner][spender]; } /** * @notice Pure function to get the name of the token. * @return The name of the token. */ function name() external pure returns (string memory) { return _NAME; } /** * @notice Pure function to get the symbol of the token. * @return The symbol of the token. */ function symbol() external pure returns (string memory) { return _SYMBOL; } /** * @notice Pure function to get the number of decimals of the token. * @return The number of decimals of the token. */ function decimals() external pure returns (uint8) { return _DECIMALS; } /** * @notice Pure function for getting the current Dharma Dai version. * @return The current Dharma Dai version. */ function getVersion() external pure returns (uint256 version) { version = _DHARMA_DAI_VERSION; } /** * @notice Internal function to mint `amount` tokens by exchanging `exchanged` * tokens to `account` and emit corresponding `Mint` & `Transfer` events. * @param account address The account to mint tokens to. * @param exchanged uint256 The amount of underlying tokens used to mint. * @param amount uint256 The amount of tokens to mint. */ function _mint(address account, uint256 exchanged, uint256 amount) internal { _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Mint(account, exchanged, amount); emit Transfer(address(0), account, amount); } /** * @notice Internal function to burn `amount` tokens by exchanging `exchanged` * tokens from `account` and emit corresponding `Redeeem` & `Transfer` events. * @param account address The account to burn tokens from. * @param exchanged uint256 The amount of underlying tokens given for burning. * @param amount uint256 The amount of tokens to burn. */ function _burn(address account, uint256 exchanged, uint256 amount) internal { uint256 balancePriorToBurn = _balances[account]; require( balancePriorToBurn >= amount, "Supplied amount exceeds account balance." ); _totalSupply = _totalSupply.sub(amount); _balances[account] = balancePriorToBurn - amount; // overflow checked above emit Transfer(account, address(0), amount); emit Redeem(account, exchanged, amount); } /** * @notice Internal function to move `amount` tokens from `sender` to * `recipient` and emit a corresponding `Transfer` event. * @param sender address The account to transfer tokens from. * @param recipient address The account to transfer tokens to. * @param amount uint256 The amount of tokens to transfer. */ function _transfer(address sender, address recipient, uint256 amount) internal { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _balances[sender] = _balances[sender].sub(amount); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } /** * @notice Internal function to set the allowance for `spender` to transfer up * to `value` tokens on behalf of `owner`. * @param owner address The account that has granted the allowance. * @param spender address The account to grant the allowance. * @param value uint256 The size of the allowance to grant. */ function _approve(address owner, address spender, uint256 value) internal { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = value; emit Approval(owner, spender, value); } /** * @notice Internal view function to get the latest dDai and cDai exchange * rates for Dai and provide the value for each. * @return The dDai and cDai exchange rate, as well as a boolean indicating if * interest accrual has been processed already or needs to be calculated and * placed in storage. */ function _getAccruedInterest() internal view returns ( uint256 dDaiExchangeRate, uint256 cDaiExchangeRate, bool fullyAccrued ) { // Get the number of blocks since the last time interest was accrued. uint256 blockDelta = block.number - _blockLastUpdated; fullyAccrued = (blockDelta == 0); // Skip calculation and read from storage if interest was already accrued. if (fullyAccrued) { dDaiExchangeRate = _dDaiExchangeRate; cDaiExchangeRate = _cDaiExchangeRate; } else { // Use cDai exchange rate to calculate the interest rate over the period. cDaiExchangeRate = _getCurrentExchangeRate(); uint256 cDaiInterestRate = ( (cDaiExchangeRate.mul(_SCALING_FACTOR)).div(_cDaiExchangeRate) ); // Get the current spread and calculate interest rate over the period. uint256 spreadInterestRate = _pow( _SPREAD.getDaiSpreadPerBlock().add(_SCALING_FACTOR), blockDelta ); // Use total cDai interest, less the spread, to set dDai exchange rate. dDaiExchangeRate = spreadInterestRate >= cDaiInterestRate ? _dDaiExchangeRate : _dDaiExchangeRate.mul( _SCALING_FACTOR.add(cDaiInterestRate - spreadInterestRate) ) / _SCALING_FACTOR; } } /** * @notice Internal view function to get the current cDai exchange rate. * @return The current cDai exchange rate, or amount of Dai that is redeemable * for each cDai (with 18 decimal places added to the returned exchange rate). */ function _getCurrentExchangeRate() internal view returns (uint256 exchangeRate) { uint256 storedExchangeRate = _CDAI.exchangeRateStored(); uint256 blockDelta = block.number.sub(_CDAI.accrualBlockNumber()); if (blockDelta == 0) return storedExchangeRate; exchangeRate = blockDelta == 0 ? storedExchangeRate : storedExchangeRate.add( storedExchangeRate.mul( _CDAI.supplyRatePerBlock().mul(blockDelta) ) / _SCALING_FACTOR ); } /** * @notice Internal view function to get the total surplus, or cDai * balance that exceeds the total dDai balance. * @return The total surplus, denominated in both Dai and in cDai. */ function _getSurplus() internal view returns ( uint256 daiSurplus, uint256 cDaiSurplus ) { (uint256 dDaiExchangeRate, uint256 cDaiExchangeRate,) = _getAccruedInterest(); // Determine the total value of all issued dDai in Dai, rounded up uint256 dDaiUnderlying = ( _totalSupply.mul(dDaiExchangeRate) / _SCALING_FACTOR ).add(1); // Compare to total underlying Dai value of all cDai held by this contract daiSurplus = ( _CDAI.balanceOf(address(this)).mul(cDaiExchangeRate) / _SCALING_FACTOR ).sub(dDaiUnderlying); // Determine the cDai equivalent of this surplus amount cDaiSurplus = (daiSurplus.mul(_SCALING_FACTOR)).div(cDaiExchangeRate); } /** * @notice View function to get the current dDai and cDai interest supply rate * per block (multiplied by 10^18). * @return The current dDai and cDai interest rates. */ function _getRatePerBlock() internal view returns ( uint256 dDaiSupplyRate, uint256 cDaiSupplyRate ) { uint256 spread = _SPREAD.getDaiSpreadPerBlock(); cDaiSupplyRate = _CDAI.supplyRatePerBlock(); dDaiSupplyRate = (spread < cDaiSupplyRate ? cDaiSupplyRate - spread : 0); } /** * @notice Internal function to take `floatIn` (i.e. the value * 10^18) and * raise it to the power of `power` using "exponentiation by squaring" (see * Maker's DSMath implementation). * @param floatIn uint256 The value. * @param power address The power to raise the value by. * @return The specified value raised to the specified power. */ function _pow(uint256 floatIn, uint256 power) internal pure returns (uint256 floatOut) { floatOut = power % 2 != 0 ? floatIn : _SCALING_FACTOR; for (power /= 2; power != 0; power /= 2) { floatIn = (floatIn.mul(floatIn)).add(_HALF_OF_SCALING_FACTOR) / _SCALING_FACTOR; if (power % 2 != 0) { floatOut = (floatIn.mul(floatOut)).add(_HALF_OF_SCALING_FACTOR) / _SCALING_FACTOR; } } } /** * @notice Internal pure function to determine if a call to cDai succeeded and * to revert, supplying the reason, if it failed. Failure can be caused by a * call that reverts, or by a call that does not revert but returns a non-zero * error code. * @param functionSelector bytes4 The function selector that was called. * @param ok bool A boolean representing whether the call returned or * reverted. * @param data bytes The data provided by the returned or reverted call. */ function _checkCompoundInteraction( bytes4 functionSelector, bool ok, bytes memory data ) internal pure { // Determine if something went wrong with the attempt. if (ok) { uint256 compoundError = abi.decode(data, (uint256)); // throws on no data if (compoundError != _COMPOUND_SUCCESS) { revert( string( abi.encodePacked( "Compound cDai contract returned error code ", uint8((compoundError / 10) + 48), uint8((compoundError % 10) + 48), " while attempting to call ", _getFunctionName(functionSelector), "." ) ) ); } } else { revert( string( abi.encodePacked( "Compound cDai contract reverted while attempting to call ", _getFunctionName(functionSelector), ": ", _decodeRevertReason(data) ) ) ); } } /** * @notice Internal pure function to get a Compound function name based on the * selector. * @param functionSelector bytes4 The function selector. * @return The name of the function as a string. */ function _getFunctionName( bytes4 functionSelector ) internal pure returns (string memory functionName) { if (functionSelector == _CDAI.mint.selector) { functionName = 'mint'; } else if (functionSelector == _CDAI.redeemUnderlying.selector) { functionName = 'redeemUnderlying'; } else if (functionSelector == _CDAI.transferFrom.selector) { functionName = 'transferFrom'; } else if (functionSelector == _CDAI.transfer.selector) { functionName = 'transfer'; } else { functionName = 'an unknown function'; } } /** * @notice Internal pure function to decode revert reasons. The revert reason * prefix is removed and the remaining string argument is decoded. * @param revertData bytes The raw data supplied alongside the revert. * @return The decoded revert reason string. */ function _decodeRevertReason( bytes memory revertData ) internal pure returns (string memory revertReason) { // Solidity prefixes revert reason with 0x08c379a0 -> Error(string) selector if ( revertData.length > 68 && // prefix (4) + position (32) + length (32) revertData[0] == byte(0x08) && revertData[1] == byte(0xc3) && revertData[2] == byte(0x79) && revertData[3] == byte(0xa0) ) { // Get the revert reason without the prefix from the revert data. bytes memory revertReasonBytes = new bytes(revertData.length - 4); for (uint256 i = 4; i < revertData.length; i++) { revertReasonBytes[i - 4] = revertData[i]; } // Decode the resultant revert reason as a string. revertReason = abi.decode(revertReasonBytes, (string)); } else { // Simply return the default, with no revert reason. revertReason = "(no revert reason)"; } } /** * @notice Modifier to determine the latest dDai and cDai exchange rates, and * to update the respective storage values if they have not already been * updated at some point in the current block, before proceeding to execution * of the rest of the decorated function. */ modifier accrues() { ( uint256 dDaiExchangeRate, uint256 cDaiExchangeRate, bool fullyAccrued ) = _getAccruedInterest(); if (!fullyAccrued) { // Update storage with dDai + cDai exchange rates as of the current block _blockLastUpdated = block.number; _dDaiExchangeRate = dDaiExchangeRate; _cDaiExchangeRate = cDaiExchangeRate; } _; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getVersion","outputs":[{"internalType":"uint256","name":"version","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"daiToReceive","type":"uint256"}],"name":"redeemUnderlyingToCToken","outputs":[{"internalType":"uint256","name":"dDaiBurned","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pullSurplus","outputs":[{"internalType":"uint256","name":"cDaiSurplus","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getSurplus","outputs":[{"internalType":"uint256","name":"cDaiSurplus","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"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"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"dDaiToBurn","type":"uint256"}],"name":"redeemToCToken","outputs":[{"internalType":"uint256","name":"cDaiReceived","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferUnderlying","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOfUnderlying","outputs":[{"internalType":"uint256","name":"daiBalance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getSpreadPerBlock","outputs":[{"internalType":"uint256","name":"rateSpread","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getSurplusUnderlying","outputs":[{"internalType":"uint256","name":"daiSurplus","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"accrualBlockNumber","outputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"dDai","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferUnderlyingFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"daiToReceive","type":"uint256"}],"name":"redeemUnderlying","outputs":[{"internalType":"uint256","name":"dDaiBurned","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"daiToSupply","type":"uint256"}],"name":"mint","outputs":[{"internalType":"uint256","name":"dDaiMinted","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"accrueInterest","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"supplyRatePerBlock","outputs":[{"internalType":"uint256","name":"dDaiInterestRate","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"exchangeRateCurrent","outputs":[{"internalType":"uint256","name":"dDaiExchangeRate","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"cDaiToSupply","type":"uint256"}],"name":"mintViaCToken","outputs":[{"internalType":"uint256","name":"dDaiMinted","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"dDaiToBurn","type":"uint256"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"daiReceived","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupplyUnderlying","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"uint256","name":"mintAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mintTokens","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"redeemer","type":"address"},{"indexed":false,"internalType":"uint256","name":"redeemAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"redeemTokens","type":"uint256"}],"name":"Redeem","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":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"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604080517f095ea7b3000000000000000000000000000000000000000000000000000000008152735d3a536e4d6dbd6114cc1ead35777bab948e3643600482015260001960248201529051736b175474e89094c44da98b954eedeac495271d0f9163095ea7b39160448083019260209291908290030181600087803b1580156200009b57600080fd5b505af1158015620000b0573d6000803e3d6000fd5b505050506040513d6020811015620000c757600080fd5b5051620000d357600080fd5b436003556b204fce5e3e250261100000006004908155604080517fbd6d894d0000000000000000000000000000000000000000000000000000000081529051735d3a536e4d6dbd6114cc1ead35777bab948e36439263bd6d894d928082019260209290918290030181600087803b1580156200014e57600080fd5b505af115801562000163573d6000803e3d6000fd5b505050506040513d60208110156200017a57600080fd5b50516005556127c0806200018f6000396000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c80636c540baf11610104578063a6afed95116100a2578063d8da64f311610071578063d8da64f314610502578063db006a751461051f578063dd62ed3e1461053c578063fea61faa1461056a576101da565b8063a6afed95146104bc578063a9059cbb146104c6578063ae9d70b0146104f2578063bd6d894d146104fa576101da565b8063852a12e3116100de578063852a12e31461044e57806395d89b411461046b578063a0712d6814610473578063a457c2d714610490576101da565b80636c540baf146103ea57806370a08231146103f25780637d33ef7a14610418576101da565b806323b872dd1161017c578063395093511161014b57806339509351146103885780633af9e669146103b457806344b5a802146103da5780634fdafdc7146103e2576101da565b806323b872dd146102eb57806327c0f03b14610321578063313ce5671461033e578063336d26921461035c576101da565b8063166d588f116101b8578063166d588f146102b657806318160ddd146102d357806319376532146102db5780632383b074146102e3576101da565b806306fdde03146101df578063095ea7b31461025c5780630d8e6e2c1461029c575b600080fd5b6101e7610572565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610221578181015183820152602001610209565b50505050905090810190601f16801561024e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102886004803603604081101561027257600080fd5b506001600160a01b0381351690602001356105aa565b604080519115158252519081900360200190f35b6102a46105c1565b60408051918252519081900360200190f35b6102a4600480360360208110156102cc57600080fd5b50356105c6565b6102a461075a565b6102a4610760565b6102a46108b1565b6102886004803603606081101561030157600080fd5b506001600160a01b038135811691602081013590911690604001356108bb565b6102a46004803603602081101561033757600080fd5b503561091a565b610346610a1f565b6040805160ff9092168252519081900360200190f35b6102886004803603604081101561037257600080fd5b506001600160a01b038135169060200135610a24565b6102886004803603604081101561039e57600080fd5b506001600160a01b038135169060200135610a88565b6102a4600480360360208110156103ca57600080fd5b50356001600160a01b0316610ac4565b6102a4610b16565b6102a4610b2b565b6102a4610b3b565b6102a46004803603602081101561040857600080fd5b50356001600160a01b0316610b41565b6102886004803603606081101561042e57600080fd5b506001600160a01b03813581169160208101359091169060400135610b5c565b6102a46004803603602081101561046457600080fd5b5035610c04565b6101e7610e2f565b6102a46004803603602081101561048957600080fd5b5035610e50565b610288600480360360408110156104a657600080fd5b506001600160a01b038135169060200135611077565b6104c46110b3565b005b610288600480360360408110156104dc57600080fd5b506001600160a01b0381351690602001356110df565b6102a46110ec565b6102a46110f6565b6102a46004803603602081101561051857600080fd5b5035611108565b6102a46004803603602081101561053557600080fd5b5035611293565b6102a46004803603604081101561055257600080fd5b506001600160a01b0381358116916020013516611447565b6102a4611472565b60408051808201909152601881527f446861726d6120446169202850726f746f74797065203129000000000000000060208201525b90565b60006105b73384846114ad565b5060015b92915050565b600090565b6000806000806105d4611599565b925092509250806105ee5743600355600483905560058290555b6004546106199061060d87670de0b6b3a764000063ffffffff6116d916565b9063ffffffff61173916565b93506106263386866117a3565b6005546000906106489061060d88670de0b6b3a764000063ffffffff6116d916565b60408051336024820152604480820184905282518083039091018152606490910182526020810180516001600160e01b031663a9059cbb60e01b17815291518151939450600093606093735d3a536e4d6dbd6114cc1ead35777bab948e36439392918291908083835b602083106106d05780518252601f1990920191602091820191016106b1565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610732576040519150601f19603f3d011682016040523d82523d6000602084013e610737565b606091505b50909250905061074f63a9059cbb60e01b83836118b3565b505050505050919050565b60025490565b60008060008061076e611599565b925092509250806107885743600355600483905560058290555b610790611b5c565b60408051737e4a8391c728fed9069b2962699ab416628b19fa6024820152604480820184905282518083039091018152606490910182526020810180516001600160e01b031663a9059cbb60e01b1781529151815193985060009450606093735d3a536e4d6dbd6114cc1ead35777bab948e36439382918083835b6020831061082a5780518252601f19909201916020918201910161080b565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461088c576040519150601f19603f3d011682016040523d82523d6000602084013e610891565b606091505b5090925090506108a963a9059cbb60e01b83836118b3565b505050505090565b60006105bb611b5c565b60006108c8848484611c98565b6001600160a01b0384166000908152600160209081526040808320338452909152902054600019811461090f5761090f853361090a848763ffffffff611dda16565b6114ad565b506001949350505050565b600080600080610928611599565b925092509250806109425743600355600483905560058290555b6000670de0b6b3a7640000610962600454886116d990919063ffffffff16565b8161096957fe5b04905061098d60055461060d670de0b6b3a7640000846116d990919063ffffffff16565b945061099a3382886117a3565b60408051336024820152604480820188905282518083039091018152606490910182526020810180516001600160e01b031663a9059cbb60e01b17815291518151600093606093735d3a536e4d6dbd6114cc1ead35777bab948e364393909290918291808383602083106106d05780518252601f1990920191602091820191016106b1565b600890565b600080600080610a32611599565b92509250925080610a4c5743600355600483905560058290555b600454600090610a6e9061060d88670de0b6b3a764000063ffffffff6116d916565b9050610a7b338883611c98565b5060019695505050505050565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916105b791859061090a908663ffffffff611e3716565b600080610acf611599565b50506001600160a01b038416600090815260208190526040902054909150670de0b6b3a764000090610b07908363ffffffff6116d916565b81610b0e57fe5b049392505050565b6000806000610b23611e91565b039392505050565b6000610b35611b5c565b50919050565b60035490565b6001600160a01b031660009081526020819052604090205490565b600080600080610b6a611599565b92509250925080610b845743600355600483905560058290555b600454600090610ba69061060d88670de0b6b3a764000063ffffffff6116d916565b9050610bb3888883611c98565b6001600160a01b03881660009081526001602090815260408083203384529091529020546000198114610bf557610bf5893361090a848663ffffffff611dda16565b50600198975050505050505050565b600080600080610c12611599565b92509250925080610c2c5743600355600483905560058290555b600454610c4b9061060d87670de0b6b3a764000063ffffffff6116d916565b9350610c583386866117a3565b60408051602480820188905282518083039091018152604490910182526020810180516001600160e01b031663852a12e360e01b17815291518151600093606093735d3a536e4d6dbd6114cc1ead35777bab948e3643939092909182918083835b60208310610cd85780518252601f199092019160209182019101610cb9565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610d3a576040519150601f19603f3d011682016040523d82523d6000602084013e610d3f565b606091505b509092509050610d5763852a12e360e01b83836118b3565b6040805163a9059cbb60e01b8152336004820152602481018990529051736b175474e89094c44da98b954eedeac495271d0f9163a9059cbb9160448083019260209291908290030181600087803b158015610db157600080fd5b505af1158015610dc5573d6000803e3d6000fd5b505050506040513d6020811015610ddb57600080fd5b5051610e25576040805162461bcd60e51b81526020600482015260146024820152732230b4903a3930b739b332b9103330b4b632b21760611b604482015290519081900360640190fd5b5050505050919050565b604080518082019091526007815266644461692d703160c81b602082015290565b600080600080610e5e611599565b92509250925080610e785743600355600483905560058290555b604080516323b872dd60e01b8152336004820152306024820152604481018790529051736b175474e89094c44da98b954eedeac495271d0f916323b872dd9160648083019260209291908290030181600087803b158015610ed857600080fd5b505af1158015610eec573d6000803e3d6000fd5b505050506040513d6020811015610f0257600080fd5b5051610f4c576040805162461bcd60e51b81526020600482015260146024820152732230b4903a3930b739b332b9103330b4b632b21760611b604482015290519081900360640190fd5b60408051602480820188905282518083039091018152604490910182526020810180516001600160e01b031663140e25ad60e31b17815291518151600093606093735d3a536e4d6dbd6114cc1ead35777bab948e3643939092909182918083835b60208310610fcc5780518252601f199092019160209182019101610fad565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461102e576040519150601f19603f3d011682016040523d82523d6000602084013e611033565b606091505b50909250905061104b63140e25ad60e31b83836118b3565b60045461106a9061060d89670de0b6b3a764000063ffffffff6116d916565b9550610e25338888611fa5565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916105b791859061090a908663ffffffff611dda16565b60008060006110c0611599565b925092509250806110da5743600355600483905560058290555b505050565b60006105b7338484611c98565b6000610b35611e91565b6000611100611599565b509092915050565b600080600080611116611599565b925092509250806111305743600355600483905560058290555b60408051336024820152306044820152606480820188905282518083039091018152608490910182526020810180516001600160e01b03166323b872dd60e01b17815291518151600093606093735d3a536e4d6dbd6114cc1ead35777bab948e3643939092909182918083835b602083106111bc5780518252601f19909201916020918201910161119d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461121e576040519150601f19603f3d011682016040523d82523d6000602084013e611223565b606091505b50909250905061123b6323b872dd60e01b83836118b3565b6000670de0b6b3a764000061125b6005548a6116d990919063ffffffff16565b8161126257fe5b04905061128660045461060d670de0b6b3a7640000846116d990919063ffffffff16565b965061074f338289611fa5565b6000806000806112a1611599565b925092509250806112bb5743600355600483905560058290555b670de0b6b3a76400006112d9600454876116d990919063ffffffff16565b816112e057fe5b0493506112ee3385876117a3565b60408051602480820187905282518083039091018152604490910182526020810180516001600160e01b031663852a12e360e01b17815291518151600093606093735d3a536e4d6dbd6114cc1ead35777bab948e3643939092909182918083835b6020831061136e5780518252601f19909201916020918201910161134f565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146113d0576040519150601f19603f3d011682016040523d82523d6000602084013e6113d5565b606091505b5090925090506113ed63852a12e360e01b83836118b3565b6040805163a9059cbb60e01b8152336004820152602481018890529051736b175474e89094c44da98b954eedeac495271d0f9163a9059cbb9160448083019260209291908290030181600087803b158015610db157600080fd5b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60008061147d611599565b50509050670de0b6b3a764000061149f826002546116d990919063ffffffff16565b816114a657fe5b0491505090565b6001600160a01b0383166114f25760405162461bcd60e51b81526004018080602001828103825260248152602001806127406024913960400191505060405180910390fd5b6001600160a01b0382166115375760405162461bcd60e51b81526004018080602001828103825260228152602001806126746022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6003546000908190430380159081156115bb57600454935060055492506116d3565b6115c3612085565b925060006115e860055461060d670de0b6b3a7640000876116d990919063ffffffff16565b90506000611686611680670de0b6b3a764000073a143fd004b3c26f8faedeb9224ec03585e63d0416001600160a01b0316632b6e55876040518163ffffffff1660e01b815260040160206040518083038186803b15801561164857600080fd5b505afa15801561165c573d6000803e3d6000fd5b505050506040513d602081101561167257600080fd5b50519063ffffffff611e3716565b84612236565b9050818110156116ca57670de0b6b3a76400006116bd6116ae8284860363ffffffff611e3716565b6004549063ffffffff6116d916565b816116c457fe5b046116ce565b6004545b955050505b50909192565b6000826116e8575060006105bb565b828202828482816116f557fe5b04146117325760405162461bcd60e51b81526004018080602001828103825260218152602001806126fa6021913960400191505060405180910390fd5b9392505050565b600080821161178f576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b600082848161179a57fe5b04949350505050565b6001600160a01b038316600090815260208190526040902054818110156117fb5760405162461bcd60e51b81526004018080602001828103825260288152602001806127646028913960400191505060405180910390fd5b60025461180e908363ffffffff611dda16565b6002556001600160a01b0384166000818152602081815260408083208686039055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3604080516001600160a01b03861681526020810185905280820184905290517fe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4ec31a9299181900360600190a150505050565b8115611a435760008180602001905160208110156118d057600080fd5b505190508015611a3d57600a8104603001600a82816118eb57fe5b066030016118f8866122de565b60405160200180602b6126cf82396001600160f81b031960f886811b8216602b84015285901b16602c8201527f207768696c6520617474656d7074696e6720746f2063616c6c20000000000000602d820152825160479091019060208401908083835b6020831061197a5780518252601f19909201916020918201910161195b565b51815160209384036101000a6000190180199092169116179052601760f91b9190930190815260408051808303601e19018152600183019182905262461bcd60e51b9091526005820184815281516025840152815191985096508695506045909101935091860191905080838360005b83811015611a025781810151838201526020016119ea565b50505050905090810190601f168015611a2f5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506110da565b611a4c836122de565b611a5582612411565b604051602001806039612696823960390183805190602001908083835b60208310611a915780518252601f199092019160209182019101611a72565b51815160209384036101000a60001901801990921691161790526101d160f51b919093019081528451600290910192850191508083835b60208310611ae75780518252601f199092019160209182019101611ac8565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f190183529384905262461bcd60e51b84526004840181815282516024860152825192975095508594506044909301928601915080838360008315611a025781810151838201526020016119ea565b600080600080611b6a611599565b50915091506000611ba86001670de0b6b3a7640000611b94866002546116d990919063ffffffff16565b81611b9b57fe5b049063ffffffff611e3716565b9050611c7181670de0b6b3a7640000611c5d85735d3a536e4d6dbd6114cc1ead35777bab948e36436001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611c2557600080fd5b505afa158015611c39573d6000803e3d6000fd5b505050506040513d6020811015611c4f57600080fd5b50519063ffffffff6116d916565b81611c6457fe5b049063ffffffff611dda16565b9450611c8f8261060d87670de0b6b3a764000063ffffffff6116d916565b93505050509091565b6001600160a01b038316611cdd5760405162461bcd60e51b815260040180806020018281038252602581526020018061271b6025913960400191505060405180910390fd5b6001600160a01b038216611d225760405162461bcd60e51b81526004018080602001828103825260238152602001806126516023913960400191505060405180910390fd5b6001600160a01b038316600090815260208190526040902054611d4b908263ffffffff611dda16565b6001600160a01b038085166000908152602081905260408082209390935590841681522054611d80908263ffffffff611e3716565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600082821115611e31576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600082820183811015611732576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600080600073a143fd004b3c26f8faedeb9224ec03585e63d0416001600160a01b0316632b6e55876040518163ffffffff1660e01b815260040160206040518083038186803b158015611ee357600080fd5b505afa158015611ef7573d6000803e3d6000fd5b505050506040513d6020811015611f0d57600080fd5b505160408051630ae9d70b60e41b81529051919250735d3a536e4d6dbd6114cc1ead35777bab948e36439163ae9d70b091600480820192602092909190829003018186803b158015611f5e57600080fd5b505afa158015611f72573d6000803e3d6000fd5b505050506040513d6020811015611f8857600080fd5b50519150818110611f9a576000611f9e565b8082035b9250509091565b600254611fb8908263ffffffff611e3716565b6002556001600160a01b038316600090815260208190526040902054611fe4908263ffffffff611e3716565b6001600160a01b0384166000818152602081815260409182902093909355805191825291810184905280820183905290517f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f9181900360600190a16040805182815290516001600160a01b038516916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a3505050565b600080735d3a536e4d6dbd6114cc1ead35777bab948e36436001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b1580156120d557600080fd5b505afa1580156120e9573d6000803e3d6000fd5b505050506040513d60208110156120ff57600080fd5b505160408051636c540baf60e01b8152905191925060009161219091735d3a536e4d6dbd6114cc1ead35777bab948e364391636c540baf91600480820192602092909190829003018186803b15801561215757600080fd5b505afa15801561216b573d6000803e3d6000fd5b505050506040513d602081101561218157600080fd5b5051439063ffffffff611dda16565b90508061219f575090506105a7565b801561222d57612228670de0b6b3a764000061221261220584735d3a536e4d6dbd6114cc1ead35777bab948e36436001600160a01b031663ae9d70b06040518163ffffffff1660e01b815260040160206040518083038186803b158015611c2557600080fd5b859063ffffffff6116d916565b8161221957fe5b8491900463ffffffff611e3716565b61222f565b815b9250505090565b60006002820661224e57670de0b6b3a7640000612250565b825b90506002820491505b81156105bb57670de0b6b3a76400006122906706f05b59d3b20000612284868063ffffffff6116d916565b9063ffffffff611e3716565b8161229757fe5b04925060028206156122d357670de0b6b3a76400006122c86706f05b59d3b20000612284868563ffffffff6116d916565b816122cf57fe5b0490505b600282049150612259565b60606001600160e01b0319821663140e25ad60e31b141561231a57506040805180820190915260048152631b5a5b9d60e21b602082015261240c565b6001600160e01b0319821663852a12e360e01b1415612360575060408051808201909152601081526f72656465656d556e6465726c79696e6760801b602082015261240c565b6001600160e01b031982166323b872dd60e01b14156123a2575060408051808201909152600c81526b7472616e7366657246726f6d60a01b602082015261240c565b6001600160e01b0319821663a9059cbb60e01b14156123e057506040805180820190915260088152673a3930b739b332b960c11b602082015261240c565b5060408051808201909152601381527230b7103ab735b737bbb710333ab731ba34b7b760691b60208201525b919050565b60606044825111801561244357508151600160fb1b90839060009061243257fe5b01602001516001600160f81b031916145b80156124705750815160c360f81b908390600190811061245f57fe5b01602001516001600160f81b031916145b801561249d57508151607960f81b908390600290811061248c57fe5b01602001516001600160f81b031916145b80156124ca57508151600560fd1b90839060039081106124b957fe5b01602001516001600160f81b031916145b1561262257606060048351036040519080825280601f01601f191660200182016040528015612500576020820181803883390190505b50905060045b83518110156125545783818151811061251b57fe5b602001015160f81c60f81b82600483038151811061253557fe5b60200101906001600160f81b031916908160001a905350600101612506565b5080806020019051602081101561256a57600080fd5b810190808051604051939291908464010000000082111561258a57600080fd5b90830190602082018581111561259f57600080fd5b82516401000000008111828201881017156125b957600080fd5b82525081516020918201929091019080838360005b838110156125e65781810151838201526020016125ce565b50505050905090810190601f1680156126135780820380516001836020036101000a031916815260200191505b5060405250505091505061240c565b5050604080518082019091526012815271286e6f2072657665727420726561736f6e2960701b60208201529056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f2061646472657373436f6d706f756e64206344616920636f6e7472616374207265766572746564207768696c6520617474656d7074696e6720746f2063616c6c20436f6d706f756e64206344616920636f6e74726163742072657475726e6564206572726f7220636f646520536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f2061646472657373537570706c69656420616d6f756e742065786365656473206163636f756e742062616c616e63652ea265627a7a72315820a58886c449a1ad0f666e674b8045c3a90bfb277e0ee4ba4eb9a4bfabdfe8c85564736f6c634300050b0032
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101da5760003560e01c80636c540baf11610104578063a6afed95116100a2578063d8da64f311610071578063d8da64f314610502578063db006a751461051f578063dd62ed3e1461053c578063fea61faa1461056a576101da565b8063a6afed95146104bc578063a9059cbb146104c6578063ae9d70b0146104f2578063bd6d894d146104fa576101da565b8063852a12e3116100de578063852a12e31461044e57806395d89b411461046b578063a0712d6814610473578063a457c2d714610490576101da565b80636c540baf146103ea57806370a08231146103f25780637d33ef7a14610418576101da565b806323b872dd1161017c578063395093511161014b57806339509351146103885780633af9e669146103b457806344b5a802146103da5780634fdafdc7146103e2576101da565b806323b872dd146102eb57806327c0f03b14610321578063313ce5671461033e578063336d26921461035c576101da565b8063166d588f116101b8578063166d588f146102b657806318160ddd146102d357806319376532146102db5780632383b074146102e3576101da565b806306fdde03146101df578063095ea7b31461025c5780630d8e6e2c1461029c575b600080fd5b6101e7610572565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610221578181015183820152602001610209565b50505050905090810190601f16801561024e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102886004803603604081101561027257600080fd5b506001600160a01b0381351690602001356105aa565b604080519115158252519081900360200190f35b6102a46105c1565b60408051918252519081900360200190f35b6102a4600480360360208110156102cc57600080fd5b50356105c6565b6102a461075a565b6102a4610760565b6102a46108b1565b6102886004803603606081101561030157600080fd5b506001600160a01b038135811691602081013590911690604001356108bb565b6102a46004803603602081101561033757600080fd5b503561091a565b610346610a1f565b6040805160ff9092168252519081900360200190f35b6102886004803603604081101561037257600080fd5b506001600160a01b038135169060200135610a24565b6102886004803603604081101561039e57600080fd5b506001600160a01b038135169060200135610a88565b6102a4600480360360208110156103ca57600080fd5b50356001600160a01b0316610ac4565b6102a4610b16565b6102a4610b2b565b6102a4610b3b565b6102a46004803603602081101561040857600080fd5b50356001600160a01b0316610b41565b6102886004803603606081101561042e57600080fd5b506001600160a01b03813581169160208101359091169060400135610b5c565b6102a46004803603602081101561046457600080fd5b5035610c04565b6101e7610e2f565b6102a46004803603602081101561048957600080fd5b5035610e50565b610288600480360360408110156104a657600080fd5b506001600160a01b038135169060200135611077565b6104c46110b3565b005b610288600480360360408110156104dc57600080fd5b506001600160a01b0381351690602001356110df565b6102a46110ec565b6102a46110f6565b6102a46004803603602081101561051857600080fd5b5035611108565b6102a46004803603602081101561053557600080fd5b5035611293565b6102a46004803603604081101561055257600080fd5b506001600160a01b0381358116916020013516611447565b6102a4611472565b60408051808201909152601881527f446861726d6120446169202850726f746f74797065203129000000000000000060208201525b90565b60006105b73384846114ad565b5060015b92915050565b600090565b6000806000806105d4611599565b925092509250806105ee5743600355600483905560058290555b6004546106199061060d87670de0b6b3a764000063ffffffff6116d916565b9063ffffffff61173916565b93506106263386866117a3565b6005546000906106489061060d88670de0b6b3a764000063ffffffff6116d916565b60408051336024820152604480820184905282518083039091018152606490910182526020810180516001600160e01b031663a9059cbb60e01b17815291518151939450600093606093735d3a536e4d6dbd6114cc1ead35777bab948e36439392918291908083835b602083106106d05780518252601f1990920191602091820191016106b1565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610732576040519150601f19603f3d011682016040523d82523d6000602084013e610737565b606091505b50909250905061074f63a9059cbb60e01b83836118b3565b505050505050919050565b60025490565b60008060008061076e611599565b925092509250806107885743600355600483905560058290555b610790611b5c565b60408051737e4a8391c728fed9069b2962699ab416628b19fa6024820152604480820184905282518083039091018152606490910182526020810180516001600160e01b031663a9059cbb60e01b1781529151815193985060009450606093735d3a536e4d6dbd6114cc1ead35777bab948e36439382918083835b6020831061082a5780518252601f19909201916020918201910161080b565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461088c576040519150601f19603f3d011682016040523d82523d6000602084013e610891565b606091505b5090925090506108a963a9059cbb60e01b83836118b3565b505050505090565b60006105bb611b5c565b60006108c8848484611c98565b6001600160a01b0384166000908152600160209081526040808320338452909152902054600019811461090f5761090f853361090a848763ffffffff611dda16565b6114ad565b506001949350505050565b600080600080610928611599565b925092509250806109425743600355600483905560058290555b6000670de0b6b3a7640000610962600454886116d990919063ffffffff16565b8161096957fe5b04905061098d60055461060d670de0b6b3a7640000846116d990919063ffffffff16565b945061099a3382886117a3565b60408051336024820152604480820188905282518083039091018152606490910182526020810180516001600160e01b031663a9059cbb60e01b17815291518151600093606093735d3a536e4d6dbd6114cc1ead35777bab948e364393909290918291808383602083106106d05780518252601f1990920191602091820191016106b1565b600890565b600080600080610a32611599565b92509250925080610a4c5743600355600483905560058290555b600454600090610a6e9061060d88670de0b6b3a764000063ffffffff6116d916565b9050610a7b338883611c98565b5060019695505050505050565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916105b791859061090a908663ffffffff611e3716565b600080610acf611599565b50506001600160a01b038416600090815260208190526040902054909150670de0b6b3a764000090610b07908363ffffffff6116d916565b81610b0e57fe5b049392505050565b6000806000610b23611e91565b039392505050565b6000610b35611b5c565b50919050565b60035490565b6001600160a01b031660009081526020819052604090205490565b600080600080610b6a611599565b92509250925080610b845743600355600483905560058290555b600454600090610ba69061060d88670de0b6b3a764000063ffffffff6116d916565b9050610bb3888883611c98565b6001600160a01b03881660009081526001602090815260408083203384529091529020546000198114610bf557610bf5893361090a848663ffffffff611dda16565b50600198975050505050505050565b600080600080610c12611599565b92509250925080610c2c5743600355600483905560058290555b600454610c4b9061060d87670de0b6b3a764000063ffffffff6116d916565b9350610c583386866117a3565b60408051602480820188905282518083039091018152604490910182526020810180516001600160e01b031663852a12e360e01b17815291518151600093606093735d3a536e4d6dbd6114cc1ead35777bab948e3643939092909182918083835b60208310610cd85780518252601f199092019160209182019101610cb9565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610d3a576040519150601f19603f3d011682016040523d82523d6000602084013e610d3f565b606091505b509092509050610d5763852a12e360e01b83836118b3565b6040805163a9059cbb60e01b8152336004820152602481018990529051736b175474e89094c44da98b954eedeac495271d0f9163a9059cbb9160448083019260209291908290030181600087803b158015610db157600080fd5b505af1158015610dc5573d6000803e3d6000fd5b505050506040513d6020811015610ddb57600080fd5b5051610e25576040805162461bcd60e51b81526020600482015260146024820152732230b4903a3930b739b332b9103330b4b632b21760611b604482015290519081900360640190fd5b5050505050919050565b604080518082019091526007815266644461692d703160c81b602082015290565b600080600080610e5e611599565b92509250925080610e785743600355600483905560058290555b604080516323b872dd60e01b8152336004820152306024820152604481018790529051736b175474e89094c44da98b954eedeac495271d0f916323b872dd9160648083019260209291908290030181600087803b158015610ed857600080fd5b505af1158015610eec573d6000803e3d6000fd5b505050506040513d6020811015610f0257600080fd5b5051610f4c576040805162461bcd60e51b81526020600482015260146024820152732230b4903a3930b739b332b9103330b4b632b21760611b604482015290519081900360640190fd5b60408051602480820188905282518083039091018152604490910182526020810180516001600160e01b031663140e25ad60e31b17815291518151600093606093735d3a536e4d6dbd6114cc1ead35777bab948e3643939092909182918083835b60208310610fcc5780518252601f199092019160209182019101610fad565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461102e576040519150601f19603f3d011682016040523d82523d6000602084013e611033565b606091505b50909250905061104b63140e25ad60e31b83836118b3565b60045461106a9061060d89670de0b6b3a764000063ffffffff6116d916565b9550610e25338888611fa5565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916105b791859061090a908663ffffffff611dda16565b60008060006110c0611599565b925092509250806110da5743600355600483905560058290555b505050565b60006105b7338484611c98565b6000610b35611e91565b6000611100611599565b509092915050565b600080600080611116611599565b925092509250806111305743600355600483905560058290555b60408051336024820152306044820152606480820188905282518083039091018152608490910182526020810180516001600160e01b03166323b872dd60e01b17815291518151600093606093735d3a536e4d6dbd6114cc1ead35777bab948e3643939092909182918083835b602083106111bc5780518252601f19909201916020918201910161119d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461121e576040519150601f19603f3d011682016040523d82523d6000602084013e611223565b606091505b50909250905061123b6323b872dd60e01b83836118b3565b6000670de0b6b3a764000061125b6005548a6116d990919063ffffffff16565b8161126257fe5b04905061128660045461060d670de0b6b3a7640000846116d990919063ffffffff16565b965061074f338289611fa5565b6000806000806112a1611599565b925092509250806112bb5743600355600483905560058290555b670de0b6b3a76400006112d9600454876116d990919063ffffffff16565b816112e057fe5b0493506112ee3385876117a3565b60408051602480820187905282518083039091018152604490910182526020810180516001600160e01b031663852a12e360e01b17815291518151600093606093735d3a536e4d6dbd6114cc1ead35777bab948e3643939092909182918083835b6020831061136e5780518252601f19909201916020918201910161134f565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146113d0576040519150601f19603f3d011682016040523d82523d6000602084013e6113d5565b606091505b5090925090506113ed63852a12e360e01b83836118b3565b6040805163a9059cbb60e01b8152336004820152602481018890529051736b175474e89094c44da98b954eedeac495271d0f9163a9059cbb9160448083019260209291908290030181600087803b158015610db157600080fd5b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60008061147d611599565b50509050670de0b6b3a764000061149f826002546116d990919063ffffffff16565b816114a657fe5b0491505090565b6001600160a01b0383166114f25760405162461bcd60e51b81526004018080602001828103825260248152602001806127406024913960400191505060405180910390fd5b6001600160a01b0382166115375760405162461bcd60e51b81526004018080602001828103825260228152602001806126746022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6003546000908190430380159081156115bb57600454935060055492506116d3565b6115c3612085565b925060006115e860055461060d670de0b6b3a7640000876116d990919063ffffffff16565b90506000611686611680670de0b6b3a764000073a143fd004b3c26f8faedeb9224ec03585e63d0416001600160a01b0316632b6e55876040518163ffffffff1660e01b815260040160206040518083038186803b15801561164857600080fd5b505afa15801561165c573d6000803e3d6000fd5b505050506040513d602081101561167257600080fd5b50519063ffffffff611e3716565b84612236565b9050818110156116ca57670de0b6b3a76400006116bd6116ae8284860363ffffffff611e3716565b6004549063ffffffff6116d916565b816116c457fe5b046116ce565b6004545b955050505b50909192565b6000826116e8575060006105bb565b828202828482816116f557fe5b04146117325760405162461bcd60e51b81526004018080602001828103825260218152602001806126fa6021913960400191505060405180910390fd5b9392505050565b600080821161178f576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b600082848161179a57fe5b04949350505050565b6001600160a01b038316600090815260208190526040902054818110156117fb5760405162461bcd60e51b81526004018080602001828103825260288152602001806127646028913960400191505060405180910390fd5b60025461180e908363ffffffff611dda16565b6002556001600160a01b0384166000818152602081815260408083208686039055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3604080516001600160a01b03861681526020810185905280820184905290517fe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4ec31a9299181900360600190a150505050565b8115611a435760008180602001905160208110156118d057600080fd5b505190508015611a3d57600a8104603001600a82816118eb57fe5b066030016118f8866122de565b60405160200180602b6126cf82396001600160f81b031960f886811b8216602b84015285901b16602c8201527f207768696c6520617474656d7074696e6720746f2063616c6c20000000000000602d820152825160479091019060208401908083835b6020831061197a5780518252601f19909201916020918201910161195b565b51815160209384036101000a6000190180199092169116179052601760f91b9190930190815260408051808303601e19018152600183019182905262461bcd60e51b9091526005820184815281516025840152815191985096508695506045909101935091860191905080838360005b83811015611a025781810151838201526020016119ea565b50505050905090810190601f168015611a2f5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506110da565b611a4c836122de565b611a5582612411565b604051602001806039612696823960390183805190602001908083835b60208310611a915780518252601f199092019160209182019101611a72565b51815160209384036101000a60001901801990921691161790526101d160f51b919093019081528451600290910192850191508083835b60208310611ae75780518252601f199092019160209182019101611ac8565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f190183529384905262461bcd60e51b84526004840181815282516024860152825192975095508594506044909301928601915080838360008315611a025781810151838201526020016119ea565b600080600080611b6a611599565b50915091506000611ba86001670de0b6b3a7640000611b94866002546116d990919063ffffffff16565b81611b9b57fe5b049063ffffffff611e3716565b9050611c7181670de0b6b3a7640000611c5d85735d3a536e4d6dbd6114cc1ead35777bab948e36436001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015611c2557600080fd5b505afa158015611c39573d6000803e3d6000fd5b505050506040513d6020811015611c4f57600080fd5b50519063ffffffff6116d916565b81611c6457fe5b049063ffffffff611dda16565b9450611c8f8261060d87670de0b6b3a764000063ffffffff6116d916565b93505050509091565b6001600160a01b038316611cdd5760405162461bcd60e51b815260040180806020018281038252602581526020018061271b6025913960400191505060405180910390fd5b6001600160a01b038216611d225760405162461bcd60e51b81526004018080602001828103825260238152602001806126516023913960400191505060405180910390fd5b6001600160a01b038316600090815260208190526040902054611d4b908263ffffffff611dda16565b6001600160a01b038085166000908152602081905260408082209390935590841681522054611d80908263ffffffff611e3716565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600082821115611e31576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600082820183811015611732576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600080600073a143fd004b3c26f8faedeb9224ec03585e63d0416001600160a01b0316632b6e55876040518163ffffffff1660e01b815260040160206040518083038186803b158015611ee357600080fd5b505afa158015611ef7573d6000803e3d6000fd5b505050506040513d6020811015611f0d57600080fd5b505160408051630ae9d70b60e41b81529051919250735d3a536e4d6dbd6114cc1ead35777bab948e36439163ae9d70b091600480820192602092909190829003018186803b158015611f5e57600080fd5b505afa158015611f72573d6000803e3d6000fd5b505050506040513d6020811015611f8857600080fd5b50519150818110611f9a576000611f9e565b8082035b9250509091565b600254611fb8908263ffffffff611e3716565b6002556001600160a01b038316600090815260208190526040902054611fe4908263ffffffff611e3716565b6001600160a01b0384166000818152602081815260409182902093909355805191825291810184905280820183905290517f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f9181900360600190a16040805182815290516001600160a01b038516916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a3505050565b600080735d3a536e4d6dbd6114cc1ead35777bab948e36436001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b1580156120d557600080fd5b505afa1580156120e9573d6000803e3d6000fd5b505050506040513d60208110156120ff57600080fd5b505160408051636c540baf60e01b8152905191925060009161219091735d3a536e4d6dbd6114cc1ead35777bab948e364391636c540baf91600480820192602092909190829003018186803b15801561215757600080fd5b505afa15801561216b573d6000803e3d6000fd5b505050506040513d602081101561218157600080fd5b5051439063ffffffff611dda16565b90508061219f575090506105a7565b801561222d57612228670de0b6b3a764000061221261220584735d3a536e4d6dbd6114cc1ead35777bab948e36436001600160a01b031663ae9d70b06040518163ffffffff1660e01b815260040160206040518083038186803b158015611c2557600080fd5b859063ffffffff6116d916565b8161221957fe5b8491900463ffffffff611e3716565b61222f565b815b9250505090565b60006002820661224e57670de0b6b3a7640000612250565b825b90506002820491505b81156105bb57670de0b6b3a76400006122906706f05b59d3b20000612284868063ffffffff6116d916565b9063ffffffff611e3716565b8161229757fe5b04925060028206156122d357670de0b6b3a76400006122c86706f05b59d3b20000612284868563ffffffff6116d916565b816122cf57fe5b0490505b600282049150612259565b60606001600160e01b0319821663140e25ad60e31b141561231a57506040805180820190915260048152631b5a5b9d60e21b602082015261240c565b6001600160e01b0319821663852a12e360e01b1415612360575060408051808201909152601081526f72656465656d556e6465726c79696e6760801b602082015261240c565b6001600160e01b031982166323b872dd60e01b14156123a2575060408051808201909152600c81526b7472616e7366657246726f6d60a01b602082015261240c565b6001600160e01b0319821663a9059cbb60e01b14156123e057506040805180820190915260088152673a3930b739b332b960c11b602082015261240c565b5060408051808201909152601381527230b7103ab735b737bbb710333ab731ba34b7b760691b60208201525b919050565b60606044825111801561244357508151600160fb1b90839060009061243257fe5b01602001516001600160f81b031916145b80156124705750815160c360f81b908390600190811061245f57fe5b01602001516001600160f81b031916145b801561249d57508151607960f81b908390600290811061248c57fe5b01602001516001600160f81b031916145b80156124ca57508151600560fd1b90839060039081106124b957fe5b01602001516001600160f81b031916145b1561262257606060048351036040519080825280601f01601f191660200182016040528015612500576020820181803883390190505b50905060045b83518110156125545783818151811061251b57fe5b602001015160f81c60f81b82600483038151811061253557fe5b60200101906001600160f81b031916908160001a905350600101612506565b5080806020019051602081101561256a57600080fd5b810190808051604051939291908464010000000082111561258a57600080fd5b90830190602082018581111561259f57600080fd5b82516401000000008111828201881017156125b957600080fd5b82525081516020918201929091019080838360005b838110156125e65781810151838201526020016125ce565b50505050905090810190601f1680156126135780820380516001836020036101000a031916815260200191505b5060405250505091505061240c565b5050604080518082019091526012815271286e6f2072657665727420726561736f6e2960701b60208201529056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f2061646472657373436f6d706f756e64206344616920636f6e7472616374207265766572746564207768696c6520617474656d7074696e6720746f2063616c6c20436f6d706f756e64206344616920636f6e74726163742072657475726e6564206572726f7220636f646520536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f2061646472657373537570706c69656420616d6f756e742065786365656473206163636f756e742062616c616e63652ea265627a7a72315820a58886c449a1ad0f666e674b8045c3a90bfb277e0ee4ba4eb9a4bfabdfe8c85564736f6c634300050b0032
Deployed Bytecode Sourcemap
4877:30632:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;4877:30632:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22932:79;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;22932:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15718:140;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;15718:140:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;23573:104;;;:::i;:::-;;;;;;;;;;;;;;;;12593:798;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;12593:798:0;;:::i;20857:87::-;;;:::i;13580:487::-;;;:::i;18805:190::-;;;:::i;16267:336::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;16267:336:0;;;;;;;;;;;;;;;;;:::i;10313:793::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;10313:793:0;;:::i;23356:79::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;15075:325;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;15075:325:0;;;;;;;;:::i;17852:222::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;17852:222:0;;;;;;;;:::i;21910:393::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21910:393:0;-1:-1:-1;;;;;21910:393:0;;:::i;20534:213::-;;;:::i;19190:198::-;;;:::i;19563:118::-;;;:::i;21545:111::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21545:111:0;-1:-1:-1;;;;;21545:111:0;;:::i;17023:507::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;17023:507:0;;;;;;;;;;;;;;;;;:::i;11491:740::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;11491:740:0;;:::i;23130:83::-;;;:::i;6991:781::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;6991:781:0;;:::i;18399:232::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;18399:232:0;;;;;;;;:::i;14211:111::-;;;:::i;:::-;;14615:148;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;14615:148:0;;;;;;;;:::i;20217:132::-;;;:::i;19837:212::-;;;:::i;8186:799::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;8186:799:0;;:::i;9294:727::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;9294:727:0;;:::i;22687:130::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;22687:130:0;;;;;;;;;;:::i;21074:258::-;;;:::i;22932:79::-;23000:5;;;;;;;;;;;;;;;;;22932:79;;:::o;15718:140::-;15785:4;15798:36;15807:10;15819:7;15828:5;15798:8;:36::i;:::-;-1:-1:-1;15848:4:0;15718:140;;;;;:::o;23573:104::-;23618:15;;23573:104::o;12593:798::-;12685:18;35143:24;35169;35195:17;35222:21;:19;:21::i;:::-;35134:109;;;;;;35257:12;35252:239;;35381:12;35361:17;:32;35402:17;:36;;;35447:17;:36;;;35252:239;12827:17;;12787:58;;12788:33;:12;5253:4;12788:33;:16;:33;:::i;:::-;12787:39;:58;:39;:58;:::i;:::-;12774:71;;12877:43;12883:10;12895:12;12909:10;12877:5;:43::i;:::-;13069:17;;13007:21;;13031:56;;:33;:12;5253:4;13031:33;:16;:33;:::i;:56::-;13227:88;;;13283:10;13227:88;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;13227:88:0;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;13207:109:0;;;;13007:80;;-1:-1:-1;13177:7:0;;13186:17;;5441:42;;13227:88;13207:109;;;25:18:-1;13207:109:0;;25:18:-1;36:153;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;13207:109:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;-1:-1;13176:140:0;;-1:-1:-1;13176:140:0;-1:-1:-1;13325:60:0;-1:-1:-1;;;13176:140:0;;13325:25;:60::i;:::-;35499:1;;;12593:798;;;;;;:::o;20857:87::-;20926:12;;20857:87;:::o;13580:487::-;13629:19;35143:24;35169;35195:17;35222:21;:19;:21::i;:::-;35134:109;;;;;;35257:12;35252:239;;35381:12;35361:17;:32;35402:17;:36;;;35447:17;:36;;;35252:239;13757:13;:11;:13::i;:::-;13909:82;;;5862:42;13909:82;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;13909:82:0;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;13889:103:0;;;;13739:31;;-1:-1:-1;13859:7:0;;-1:-1:-1;13868:17:0;;5441:42;;13889:103;;;;25:18:-1;36:153;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;13889:103:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;-1:-1;13858:134:0;;-1:-1:-1;13858:134:0;-1:-1:-1;14001:60:0;-1:-1:-1;;;13858:134:0;;14001:25;:60::i;:::-;35499:1;;13580:487;;;;:::o;18805:190::-;18850:19;18976:13;:11;:13::i;16267:336::-;16368:4;16381:36;16391:6;16399:9;16410:6;16381:9;:36::i;:::-;-1:-1:-1;;;;;16444:19:0;;16424:17;16444:19;;;:11;:19;;;;;;;;16464:10;16444:31;;;;;;;;-1:-1:-1;;16486:24:0;;16482:98;;16521:51;16530:6;16538:10;16550:21;:9;16564:6;16550:21;:13;:21;:::i;:::-;16521:8;:51::i;:::-;-1:-1:-1;16593:4:0;;16267:336;-1:-1:-1;;;;16267:336:0:o;10313:793::-;10393:20;35143:24;35169;35195:17;35222:21;:19;:21::i;:::-;35134:109;;;;;;35257:12;35252:239;;35381:12;35361:17;:32;35402:17;:36;;;35447:17;:36;;;35252:239;10491:21;5253:4;10515:33;10530:17;;10515:10;:14;;:33;;;;:::i;:::-;:51;;;;;;10491:75;;10668:59;10709:17;;10669:34;5253:4;10669:13;:17;;:34;;;;:::i;10668:59::-;10653:74;;10759:44;10765:10;10777:13;10792:10;10759:5;:44::i;:::-;10943:87;;;10999:10;10943:87;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;10943:87:0;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;10923:108:0;;;;10893:7;;10902:17;;5441:42;;10943:87;;10923:108;;;;;;25:18:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;23356:79:0;5184:1;23356:79;:::o;15075:325::-;15174:4;35143:24;35169;35195:17;35222:21;:19;:21::i;:::-;35134:109;;;;;;35257:12;35252:239;;35381:12;35361:17;:32;35402:17;:36;;;35447:17;:36;;;35252:239;15305:17;;15250:18;;15271:52;;15272:27;:6;5253:4;15272:27;:10;:27;:::i;15271:52::-;15250:73;;15332:44;15342:10;15354:9;15365:10;15332:9;:44::i;:::-;-1:-1:-1;15390:4:0;;15075:325;-1:-1:-1;;;;;;15075:325:0:o;17852:222::-;17974:10;17944:4;17995:23;;;:11;:23;;;;;;;;-1:-1:-1;;;;;17995:32:0;;;;;;;;;;17944:4;;17957:93;;17986:7;;17995:48;;18032:10;17995:48;:36;:48;:::i;21910:393::-;21989:18;22092:24;22122:21;:19;:21::i;:::-;-1:-1:-1;;;;;;;22239:18:0;;:9;:18;;;;;;;;;;;22091:52;;-1:-1:-1;5253:4:0;;22239:40;;22091:52;22239:40;:22;:40;:::i;:::-;:58;;;;;;;21910:393;-1:-1:-1;;;21910:393:0:o;20534:213::-;20586:18;20614:24;20640;20668:18;:16;:18::i;:::-;20706:35;;20534:213;-1:-1:-1;;;20534:213:0:o;19190:198::-;19245:18;19369:13;:11;:13::i;:::-;-1:-1:-1;19352:30:0;19190:198;-1:-1:-1;19190:198:0:o;19563:118::-;19658:17;;;19563:118::o;21545:111::-;-1:-1:-1;;;;;21632:18:0;21604:12;21632:18;;;;;;;;;;;;21545:111::o;17023:507::-;17142:4;35143:24;35169;35195:17;35222:21;:19;:21::i;:::-;35134:109;;;;;;35257:12;35252:239;;35381:12;35361:17;:32;35402:17;:36;;;35447:17;:36;;;35252:239;17273:17;;17218:18;;17239:52;;17240:27;:6;5253:4;17240:27;:10;:27;:::i;17239:52::-;17218:73;;17300:40;17310:6;17318:9;17329:10;17300:9;:40::i;:::-;-1:-1:-1;;;;;17367:19:0;;17347:17;17367:19;;;:11;:19;;;;;;;;17387:10;17367:31;;;;;;;;-1:-1:-1;;17409:24:0;;17405:102;;17444:55;17453:6;17461:10;17473:25;:9;17487:10;17473:25;:13;:25;:::i;17444:55::-;-1:-1:-1;17520:4:0;;17023:507;-1:-1:-1;;;;;;;;17023:507:0:o;11491:740::-;11575:18;35143:24;35169;35195:17;35222:21;:19;:21::i;:::-;35134:109;;;;;;35257:12;35252:239;;35381:12;35361:17;:32;35402:17;:36;;;35447:17;:36;;;35252:239;11717:17;;11677:58;;11678:33;:12;5253:4;11678:33;:16;:33;:::i;11677:58::-;11664:71;;11767:43;11773:10;11785:12;11799:10;11767:5;:43::i;:::-;11945:83;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;11945:83:0;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;11925:104:0;;;;11895:7;;11904:17;;5441:42;;11945:83;;11925:104;;;;;;25:18:-1;36:153;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;11925:104:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;-1:-1;11894:135:0;;-1:-1:-1;11894:135:0;-1:-1:-1;12038:68:0;-1:-1:-1;;;11894:135:0;;12038:25;:68::i;:::-;12161:39;;;-1:-1:-1;;;12161:39:0;;12175:10;12161:39;;;;;;;;;;;;5567:42;;12161:13;;:39;;;;;;;;;;;;;;-1:-1:-1;5567:42:0;12161:39;;;5:2:-1;;;;30:1;27;20:12;5:2;12161:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;12161:39:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;12161:39:0;12153:72;;;;;-1:-1:-1;;;12153:72:0;;;;;;;;;;;;-1:-1:-1;;;12153:72:0;;;;;;;;;;;;;;;35499:1;;11491:740;;;;;;:::o;23130:83::-;23200:7;;;;;;;;;;;;-1:-1:-1;;;23200:7:0;;;;23130:83;:::o;6991:781::-;7062:18;35143:24;35169;35195:17;35222:21;:19;:21::i;:::-;35134:109;;;;;;35257:12;35252:239;;35381:12;35361:17;:32;35402:17;:36;;;35447:17;:36;;;35252:239;7179:57;;;-1:-1:-1;;;7179:57:0;;7197:10;7179:57;;;;7217:4;7179:57;;;;;;;;;;;;5567:42;;7179:17;;:57;;;;;;;;;;;;;;-1:-1:-1;5567:42:0;7179:57;;;5:2:-1;;;;30:1;27;20:12;5:2;7179:57:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;7179:57:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;7179:57:0;7163:111;;;;;-1:-1:-1;;;7163:111:0;;;;;;;;;;;;-1:-1:-1;;;7163:111:0;;;;;;;;;;;;;;;7407:70;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;7407:70:0;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;7387:91:0;;;;7357:7;;7366:17;;5441:42;;7407:70;;7387:91;;;;;;25:18:-1;36:153;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;7387:91:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;-1:-1;7356:122:0;;-1:-1:-1;7356:122:0;-1:-1:-1;7487:56:0;-1:-1:-1;;;7356:122:0;;7487:25;:56::i;:::-;7664:17;;7625:57;;7626:32;:11;5253:4;7626:32;:15;:32;:::i;7625:57::-;7612:70;;7724:42;7730:10;7742:11;7755:10;7724:5;:42::i;18399:232::-;18526:10;18496:4;18547:23;;;:11;:23;;;;;;;;-1:-1:-1;;;;;18547:32:0;;;;;;;;;;18496:4;;18509:98;;18538:7;;18547:53;;18584:15;18547:53;:36;:53;:::i;14211:111::-;35143:24;35169;35195:17;35222:21;:19;:21::i;:::-;35134:109;;;;;;35257:12;35252:239;;35381:12;35361:17;:32;35402:17;:36;;;35447:17;:36;;;35252:239;14211:111;;;:::o;14615:148::-;14686:4;14699:40;14709:10;14721:9;14732:6;14699:9;:40::i;20217:132::-;20270:24;20325:18;:16;:18::i;19837:212::-;19891:24;20022:21;:19;:21::i;:::-;-1:-1:-1;19999:44:0;;19837:212;-1:-1:-1;;19837:212:0:o;8186:799::-;8267:18;35143:24;35169;35195:17;35222:21;:19;:21::i;:::-;35134:109;;;;;;35257:12;35252:239;;35381:12;35361:17;:32;35402:17;:36;;;35447:17;:36;;;35252:239;8420:106;;;8480:10;8420:106;;;;8500:4;8420:106;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;8420:106:0;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;8400:127:0;;;;8370:7;;8379:17;;5441:42;;8420:106;;8400:127;;;;;;25:18:-1;36:153;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;8400:127:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;-1:-1;8369:158:0;;-1:-1:-1;8369:158:0;-1:-1:-1;8536:64:0;-1:-1:-1;;;8369:158:0;;8536:25;:64::i;:::-;8675:21;5253:4;8699:35;8716:17;;8699:12;:16;;:35;;;;:::i;:::-;:53;;;;;;8675:77;;8834:59;8875:17;;8835:34;5253:4;8835:13;:17;;:34;;;;:::i;8834:59::-;8821:72;;8935:44;8941:10;8953:13;8968:10;8935:5;:44::i;9294:727::-;9366:19;35143:24;35169;35195:17;35222:21;:19;:21::i;:::-;35134:109;;;;;;35257:12;35252:239;;35381:12;35361:17;:32;35402:17;:36;;;35447:17;:36;;;35252:239;5253:4;9477:33;9492:17;;9477:10;:14;;:33;;;;:::i;:::-;:51;;;;;;9463:65;;9560:42;9566:10;9578:11;9591:10;9560:5;:42::i;:::-;9737:82;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;9737:82:0;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;9717:103:0;;;;9687:7;;9696:17;;5441:42;;9737:82;;9717:103;;;;;;25:18:-1;36:153;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;9717:103:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;-1:-1;9686:134:0;;-1:-1:-1;9686:134:0;-1:-1:-1;9829:68:0;-1:-1:-1;;;9686:134:0;;9829:25;:68::i;:::-;9952:38;;;-1:-1:-1;;;9952:38:0;;9966:10;9952:38;;;;;;;;;;;;5567:42;;9952:13;;:38;;;;;;;;;;;;;;-1:-1:-1;5567:42:0;9952:38;;;5:2:-1;;;;30:1;27;20:12;22687:130:0;-1:-1:-1;;;;;22784:18:0;;;22761:7;22784:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;22687:130::o;21074:258::-;21130:7;21147:24;21177:21;:19;:21::i;:::-;21146:52;;;;5253:4;21274:34;21291:16;21274:12;;:16;;:34;;;;:::i;:::-;:52;;;;;;21267:59;;;21074:258;:::o;26283:317::-;-1:-1:-1;;;;;26372:19:0;;26364:68;;;;-1:-1:-1;;;26364:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;26447:21:0;;26439:68;;;;-1:-1:-1;;;26439:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;26516:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:35;;;26563:31;;;;;;;;;;;;;;;;;26283:317;;;:::o;26937:1299::-;27190:17;;26997:24;;;;27175:12;:32;27230:15;;;27335:896;;;;27381:17;;27362:36;;27426:17;;27407:36;;27335:896;;;27566:25;:23;:25::i;:::-;27547:44;;27600:24;27638:62;27682:17;;27639:37;5253:4;27639:16;:20;;:37;;;;:::i;27638:62::-;27600:109;;27798:26;27827:87;27842:51;5253:4;5714:42;-1:-1:-1;;;;;27842:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;27842:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;27842:30:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;27842:30:0;;:51;:34;:51;:::i;:::-;27895:10;27827:4;:87::i;:::-;27798:116;;28045:16;28023:18;:38;;:200;;5253:4;28102:103;28136:58;5253:4;28156:37;;;28136:58;:19;:58;:::i;:::-;28102:17;;;:103;:21;:103;:::i;:::-;:121;;;;;;28023:200;;;28073:17;;28023:200;28004:219;;27335:896;;;26937:1299;;;;:::o;4016:222::-;4074:7;4094:6;4090:37;;-1:-1:-1;4118:1:0;4111:8;;4090:37;4147:5;;;4151:1;4147;:5;:1;4167:5;;;;;:10;4159:56;;;;-1:-1:-1;;;4159:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4231:1;4016:222;-1:-1:-1;;;4016:222:0:o;4244:165::-;4302:7;4330:1;4326;:5;4318:44;;;;;-1:-1:-1;;;4318:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;4369:9;4385:1;4381;:5;;;;;;;4244:165;-1:-1:-1;;;;4244:165:0:o;24718:464::-;-1:-1:-1;;;;;24830:18:0;;24801:26;24830:18;;;;;;;;;;;24871:28;;;;24855:95;;;;-1:-1:-1;;;24855:95:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24974:12;;:24;;24991:6;24974:24;:16;:24;:::i;:::-;24959:12;:39;-1:-1:-1;;;;;25005:18:0;;:9;:18;;;;;;;;;;;25026:27;;;25005:48;;25093:37;;;;;;;25005:9;;:18;25093:37;;;;;;;;;;;25142:34;;;-1:-1:-1;;;;;25142:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;24718:464;;;;:::o;31730:1011::-;31913:2;31909:827;;;31926:21;31961:4;31950:27;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;31950:27:0;;-1:-1:-1;32011:34:0;;32007:432;;32216:2;32200:13;:18;32222:2;32199:25;32265:2;32249:13;:18;;;;;;32271:2;32248:25;32336:34;32353:16;32336;:34::i;:::-;32098:307;;;;;;;;;-1:-1:-1;;;;;;32098:307:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;-1:-1;;;32098:307:0;;;;;;;;;;26:21:-1;;;-1:-1;;22:32;6:49;;274:1;32098:307:0;;;;;;-1:-1:-1;;;32058:371:0;;;;;;;;;;;;;;;;;32098:307;;-1:-1:-1;32058:371:0;-1:-1:-1;32058:371:0;;-1:-1:-1;32058:371:0;;;;;-1:-1:-1;32058:371:0;;;;;-1:-1:-1;32058:371:0;;;-1:-1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;32058:371:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32007:432;31909:827;;;;32602:34;32619:16;32602;:34::i;:::-;32670:25;32690:4;32670:19;:25::i;:::-;32497:211;;;;;;;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;-1:-1;;;32497:211:0;;;;;;;;;;;;;;;;;-1:-1:-1;32497:211:0;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;32497:211:0;;;;;;;26:21:-1;;;-1:-1;;22:32;6:49;;32497:211:0;;;;-1:-1:-1;;;32461:267:0;;;;;;;;;;;;;;;;32497:211;;-1:-1:-1;32461:267:0;-1:-1:-1;32461:267:0;;-1:-1:-1;32461:267:0;;;;;;;;-1:-1:-1;32461:267:0;;;-1:-1:-1;27:10;;8:100;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;29186:715:0;29238:18;29258:19;29291:24;29317;29346:21;:19;:21::i;:::-;29290:77;;;;;29448:22;29473:75;29546:1;5253:4;29482:34;29499:16;29482:12;;:16;;:34;;;;:::i;:::-;:52;;;;;;;29473:75;:72;:75;:::i;:::-;29448:100;;29650:106;29741:14;5253:4;29659:52;29694:16;5441:42;-1:-1:-1;;;;;29659:15:0;;29683:4;29659:30;;;;;;;;;;;;;-1:-1:-1;;;;;29659:30:0;-1:-1:-1;;;;;29659:30:0;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;29659:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;29659:30:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;29659:30:0;;:52;:34;:52;:::i;:::-;:70;;;;;;;29650:106;:90;:106;:::i;:::-;29637:119;-1:-1:-1;29840:55:0;29878:16;29841:31;29637:119;5253:4;29841:31;:14;:31;:::i;29840:55::-;29826:69;;29186:715;;;;;:::o;25529:407::-;-1:-1:-1;;;;;25623:20:0;;25615:70;;;;-1:-1:-1;;;25615:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;25700:23:0;;25692:71;;;;-1:-1:-1;;;25692:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;25792:17:0;;:9;:17;;;;;;;;;;;:29;;25814:6;25792:29;:21;:29;:::i;:::-;-1:-1:-1;;;;;25772:17:0;;;:9;:17;;;;;;;;;;;:49;;;;25851:20;;;;;;;:32;;25876:6;25851:32;:24;:32;:::i;:::-;-1:-1:-1;;;;;25828:20:0;;;:9;:20;;;;;;;;;;;;:55;;;;25895:35;;;;;;;25828:20;;25895:35;;;;;;;;;;;;;25529:407;;;:::o;3840:170::-;3898:7;3927:1;3922;:6;;3914:49;;;;;-1:-1:-1;;;3914:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3982:5:0;;;3840:170::o;3667:167::-;3725:7;3753:5;;;3773:6;;;;3765:46;;;;;-1:-1:-1;;;3765:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;30098:298;30155:22;30179;30214:14;5714:42;-1:-1:-1;;;;;30231:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;30231:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;30231:30:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;30231:30:0;30285:26;;;-1:-1:-1;;;30285:26:0;;;;30231:30;;-1:-1:-1;5441:42:0;;30285:24;;:26;;;;;30231:30;;30285:26;;;;;;;;5441:42;30285:26;;;5:2:-1;;;;30:1;27;20:12;5:2;30285:26:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;30285:26:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;30285:26:0;;-1:-1:-1;30336:23:0;;;:53;;30388:1;30336:53;;;30379:6;30362:14;:23;30336:53;30318:72;;30098:298;;;:::o;24051:281::-;24149:12;;:24;;24166:6;24149:24;:16;:24;:::i;:::-;24134:12;:39;-1:-1:-1;;;;;24201:18:0;;:9;:18;;;;;;;;;;;:30;;24224:6;24201:30;:22;:30;:::i;:::-;-1:-1:-1;;;;;24180:18:0;;:9;:18;;;;;;;;;;;;:51;;;;24245:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;24289:37;;;;;;;;-1:-1:-1;;;;;24289:37:0;;;24306:1;;24289:37;;;;;;;;;24051:281;;;:::o;28496:478::-;28554:20;28583:26;5441:42;-1:-1:-1;;;;;28612:24:0;;:26;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;28612:26:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;28612:26:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;28612:26:0;28683;;;-1:-1:-1;;;28683:26:0;;;;28612;;-1:-1:-1;28645:18:0;;28666:44;;5441:42;;28683:24;;:26;;;;;28612;;28683;;;;;;;;5441:42;28683:26;;;5:2:-1;;;;30:1;27;20:12;5:2;28683:26:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;28683:26:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;28683:26:0;28666:12;;:44;:16;:44;:::i;:::-;28645:65;-1:-1:-1;28723:15:0;28719:46;;-1:-1:-1;28747:18:0;-1:-1:-1;28740:25:0;;28719:46;28789:15;;:179;;28828:140;5253:4;28859:84;28892:42;28923:10;5441:42;-1:-1:-1;;;;;28892:24:0;;:26;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;28892:42:0;28859:18;;:84;:22;:84;:::i;:::-;:102;;;;;28828:18;;28859:102;;28828:140;:22;:140;:::i;:::-;28789:179;;;28807:18;28789:179;28774:194;;28496:478;;;:::o;30777:430::-;30846:16;30890:1;30882:5;:9;:42;;5253:4;30882:42;;;30899:7;30882:42;30871:53;-1:-1:-1;30947:1:0;30938:10;;;;30933:269;30950:10;;30933:269;;5253:4;30993:51;5314:4;30994:20;31006:7;;30994:20;:11;:20;:::i;:::-;30993:26;:51;:26;:51;:::i;:::-;:69;;;;;;;-1:-1:-1;31085:1:0;31077:5;:9;:14;31073:122;;5253:4;31115:52;5314:4;31116:21;:7;31128:8;31116:21;:11;:21;:::i;31115:52::-;:70;;;;;;31104:81;;31073:122;30971:1;30962:10;;;;30933:269;;32971:581;33055:26;-1:-1:-1;;;;;;33094:39:0;;-1:-1:-1;;;33094:39:0;33090:457;;;-1:-1:-1;33144:21:0;;;;;;;;;;;;-1:-1:-1;;;33144:21:0;;;;33090:457;;;-1:-1:-1;;;;;;33183:51:0;;-1:-1:-1;;;33183:51:0;33179:368;;;-1:-1:-1;33245:33:0;;;;;;;;;;;;-1:-1:-1;;;33245:33:0;;;;33179:368;;;-1:-1:-1;;;;;;33296:47:0;;-1:-1:-1;;;33296:47:0;33292:255;;;-1:-1:-1;33354:29:0;;;;;;;;;;;;-1:-1:-1;;;33354:29:0;;;;33292:255;;;-1:-1:-1;;;;;;33401:43:0;;-1:-1:-1;;;33401:43:0;33397:150;;;-1:-1:-1;33455:25:0;;;;;;;;;;;;-1:-1:-1;;;33455:25:0;;;;33397:150;;;-1:-1:-1;33503:36:0;;;;;;;;;;;;-1:-1:-1;;;33503:36:0;;;;33397:150;32971:581;;;:::o;33845:960::-;33932:26;34081:2;34061:10;:17;:22;:104;;;;-1:-1:-1;34138:13:0;;-1:-1:-1;;;34155:10:0;34138;;34149:1;;34138:13;;;;;;;;-1:-1:-1;;;;;;34138:13:0;:27;34061:104;:142;;;;-1:-1:-1;34176:13:0;;-1:-1:-1;;;34193:10:0;34176;;34187:1;;34176:13;;;;;;;;;;-1:-1:-1;;;;;;34176:13:0;:27;34061:142;:180;;;;-1:-1:-1;34214:13:0;;-1:-1:-1;;;34231:10:0;34214;;34225:1;;34214:13;;;;;;;;;;-1:-1:-1;;;;;;34214:13:0;:27;34061:180;:218;;;;-1:-1:-1;34252:13:0;;-1:-1:-1;;;34269:10:0;34252;;34263:1;;34252:13;;;;;;;;;;-1:-1:-1;;;;;;34252:13:0;:27;34061:218;34049:751;;;34369:30;34432:1;34412:10;:17;:21;34402:32;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;104:10;34402:32:0;87:34:-1;135:17;;-1:-1;34402:32:0;-1:-1:-1;34369:65:0;-1:-1:-1;34460:1:0;34443:109;34467:10;:17;34463:1;:21;34443:109;;;34529:10;34540:1;34529:13;;;;;;;;;;;;;;;;34502:17;34524:1;34520;:5;34502:24;;;;;;;;;;;:40;-1:-1:-1;;;;;34502:40:0;;;;;;;;-1:-1:-1;34486:3:0;;34443:109;;;;34646:17;34635:39;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;34635:39:0;;;;;;;;;;;;;19:11:-1;14:3;11:20;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;213:10;;261:11;244:29;;285:43;;;282:58;-1:-1;233:115;230:2;;;361:1;358;351:12;230:2;372:25;;-1:-1;34635:39:0;;420:4:-1;411:14;;;;34635:39:0;;;;;411:14:-1;34635:39:0;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;34635:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34620:54;;34049:751;;;;-1:-1:-1;;34757:35:0;;;;;;;;;;;;-1:-1:-1;;;34757:35:0;;;;;33845:960::o
Swarm Source
bzzr://a58886c449a1ad0f666e674b8045c3a90bfb277e0ee4ba4eb9a4bfabdfe8c855
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.