More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 587 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Redeem | 13820536 | 1170 days ago | IN | 0 ETH | 0.00384403 | ||||
Redeem | 13766819 | 1178 days ago | IN | 0 ETH | 0.02220641 | ||||
Redeem | 13761309 | 1179 days ago | IN | 0 ETH | 0.00606797 | ||||
Redeem | 13689271 | 1190 days ago | IN | 0 ETH | 0.02346636 | ||||
Redeem | 13685049 | 1191 days ago | IN | 0 ETH | 0.00619485 | ||||
Redeem | 13681594 | 1192 days ago | IN | 0 ETH | 0.03278601 | ||||
Redeem | 13679079 | 1192 days ago | IN | 0 ETH | 0.03457965 | ||||
Redeem | 13678651 | 1192 days ago | IN | 0 ETH | 0.03391497 | ||||
Redeem | 13678576 | 1192 days ago | IN | 0 ETH | 0.03272839 | ||||
Redeem | 13678526 | 1192 days ago | IN | 0 ETH | 0.03558344 | ||||
Redeem | 13676518 | 1192 days ago | IN | 0 ETH | 0.02439338 | ||||
Redeem | 13676272 | 1192 days ago | IN | 0 ETH | 0.02508243 | ||||
Redeem | 13675475 | 1193 days ago | IN | 0 ETH | 0.00544495 | ||||
Redeem | 13674909 | 1193 days ago | IN | 0 ETH | 0.02737188 | ||||
Redeem | 13674899 | 1193 days ago | IN | 0 ETH | 0.04253955 | ||||
Redeem | 13674030 | 1193 days ago | IN | 0 ETH | 0.02318281 | ||||
Redeem | 13670984 | 1193 days ago | IN | 0 ETH | 0.02330729 | ||||
Redeem | 13670445 | 1193 days ago | IN | 0 ETH | 0.02134232 | ||||
Redeem | 13670120 | 1193 days ago | IN | 0 ETH | 0.01689071 | ||||
Redeem | 13669106 | 1194 days ago | IN | 0 ETH | 0.00694715 | ||||
Redeem | 13668198 | 1194 days ago | IN | 0 ETH | 0.02948989 | ||||
Redeem | 13668069 | 1194 days ago | IN | 0 ETH | 0.02635391 | ||||
Redeem | 13667554 | 1194 days ago | IN | 0 ETH | 0.03086955 | ||||
Redeem | 13665951 | 1194 days ago | IN | 0 ETH | 0.02454405 | ||||
Redeem | 13665721 | 1194 days ago | IN | 0 ETH | 0.03128806 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
OlympusBondDepository
Compiler Version
v0.7.5+commit.eb77ed08
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.7.5; interface IOwnable { function policy() external view returns (address); function renounceManagement() external; function pushManagement( address newOwner_ ) external; function pullManagement() external; } contract Ownable is IOwnable { address internal _owner; address internal _newOwner; event OwnershipPushed(address indexed previousOwner, address indexed newOwner); event OwnershipPulled(address indexed previousOwner, address indexed newOwner); constructor () { _owner = msg.sender; emit OwnershipPushed( address(0), _owner ); } function policy() public view override returns (address) { return _owner; } modifier onlyPolicy() { require( _owner == msg.sender, "Ownable: caller is not the owner" ); _; } function renounceManagement() public virtual override onlyPolicy() { emit OwnershipPushed( _owner, address(0) ); _owner = address(0); } function pushManagement( address newOwner_ ) public virtual override onlyPolicy() { require( newOwner_ != address(0), "Ownable: new owner is the zero address"); emit OwnershipPushed( _owner, newOwner_ ); _newOwner = newOwner_; } function pullManagement() public virtual override { require( msg.sender == _newOwner, "Ownable: must be new owner to pull"); emit OwnershipPulled( _owner, _newOwner ); _owner = _newOwner; } } 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) { return sub(a, b, "SafeMath: subtraction overflow"); } function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); 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) { return div(a, b, "SafeMath: division by zero"); } function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; return c; } function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } function sqrrt(uint256 a) internal pure returns (uint c) { if (a > 3) { c = a; uint b = add( div( a, 2), 1 ); while (b < c) { c = b; b = div( add( div( a, b ), b), 2 ); } } else if (a != 0) { c = 1; } } } library Address { function isContract(address account) internal view returns (bool) { uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, errorMessage); } function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: weiValue }(data); if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { if (returndata.length > 0) { assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } function addressToString(address _address) internal pure returns(string memory) { bytes32 _bytes = bytes32(uint256(_address)); bytes memory HEX = "0123456789abcdef"; bytes memory _addr = new bytes(42); _addr[0] = '0'; _addr[1] = 'x'; for(uint256 i = 0; i < 20; i++) { _addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)]; _addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)]; } return string(_addr); } } interface IERC20 { function decimals() external view returns (uint8); function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); 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); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); } abstract contract ERC20 is IERC20 { using SafeMath for uint256; // TODO comment actual hash value. bytes32 constant private ERC20TOKEN_ERC1820_INTERFACE_ID = keccak256( "ERC20Token" ); mapping (address => uint256) internal _balances; mapping (address => mapping (address => uint256)) internal _allowances; uint256 internal _totalSupply; string internal _name; string internal _symbol; uint8 internal _decimals; constructor (string memory name_, string memory symbol_, uint8 decimals_) { _name = name_; _symbol = symbol_; _decimals = decimals_; } function name() public view returns (string memory) { return _name; } function symbol() public view returns (string memory) { return _symbol; } function decimals() public view override returns (uint8) { return _decimals; } function totalSupply() public view override returns (uint256) { return _totalSupply; } function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(msg.sender, recipient, amount); return true; } function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(msg.sender, spender, amount); return true; } function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { _transfer(sender, recipient, amount); _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue)); return true; } function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } function _transfer(address sender, address recipient, uint256 amount) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } function _mint(address account_, uint256 ammount_) internal virtual { require(account_ != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address( this ), account_, ammount_); _totalSupply = _totalSupply.add(ammount_); _balances[account_] = _balances[account_].add(ammount_); emit Transfer(address( this ), account_, ammount_); } function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } function _beforeTokenTransfer( address from_, address to_, uint256 amount_ ) internal virtual { } } interface IERC2612Permit { function permit( address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; function nonces(address owner) external view returns (uint256); } library Counters { using SafeMath for uint256; struct Counter { uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { counter._value += 1; } function decrement(Counter storage counter) internal { counter._value = counter._value.sub(1); } } abstract contract ERC20Permit is ERC20, IERC2612Permit { using Counters for Counters.Counter; mapping(address => Counters.Counter) private _nonces; // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; bytes32 public DOMAIN_SEPARATOR; constructor() { uint256 chainID; assembly { chainID := chainid() } DOMAIN_SEPARATOR = keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name())), keccak256(bytes("1")), // Version chainID, address(this) ) ); } function permit( address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual override { require(block.timestamp <= deadline, "Permit: expired deadline"); bytes32 hashStruct = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, amount, _nonces[owner].current(), deadline)); bytes32 _hash = keccak256(abi.encodePacked(uint16(0x1901), DOMAIN_SEPARATOR, hashStruct)); address signer = ecrecover(_hash, v, r, s); require(signer != address(0) && signer == owner, "ZeroSwapPermit: Invalid signature"); _nonces[owner].increment(); _approve(owner, spender, amount); } function nonces(address owner) public view override returns (uint256) { return _nonces[owner].current(); } } library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } function safeApprove(IERC20 token, address spender, uint256 value) internal { require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function _callOptionalReturn(IERC20 token, bytes memory data) private { bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } library FullMath { function fullMul(uint256 x, uint256 y) private pure returns (uint256 l, uint256 h) { uint256 mm = mulmod(x, y, uint256(-1)); l = x * y; h = mm - l; if (mm < l) h -= 1; } function fullDiv( uint256 l, uint256 h, uint256 d ) private pure returns (uint256) { uint256 pow2 = d & -d; d /= pow2; l /= pow2; l += h * ((-pow2) / pow2 + 1); uint256 r = 1; r *= 2 - d * r; r *= 2 - d * r; r *= 2 - d * r; r *= 2 - d * r; r *= 2 - d * r; r *= 2 - d * r; r *= 2 - d * r; r *= 2 - d * r; return l * r; } function mulDiv( uint256 x, uint256 y, uint256 d ) internal pure returns (uint256) { (uint256 l, uint256 h) = fullMul(x, y); uint256 mm = mulmod(x, y, d); if (mm > l) h -= 1; l -= mm; require(h < d, 'FullMath::mulDiv: overflow'); return fullDiv(l, h, d); } } library FixedPoint { struct uq112x112 { uint224 _x; } struct uq144x112 { uint256 _x; } uint8 private constant RESOLUTION = 112; uint256 private constant Q112 = 0x10000000000000000000000000000; uint256 private constant Q224 = 0x100000000000000000000000000000000000000000000000000000000; uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff; // decimal of UQ*x112 (lower 112 bits) function decode(uq112x112 memory self) internal pure returns (uint112) { return uint112(self._x >> RESOLUTION); } function decode112with18(uq112x112 memory self) internal pure returns (uint) { return uint(self._x) / 5192296858534827; } function fraction(uint256 numerator, uint256 denominator) internal pure returns (uq112x112 memory) { require(denominator > 0, 'FixedPoint::fraction: division by zero'); if (numerator == 0) return FixedPoint.uq112x112(0); if (numerator <= uint144(-1)) { uint256 result = (numerator << RESOLUTION) / denominator; require(result <= uint224(-1), 'FixedPoint::fraction: overflow'); return uq112x112(uint224(result)); } else { uint256 result = FullMath.mulDiv(numerator, Q112, denominator); require(result <= uint224(-1), 'FixedPoint::fraction: overflow'); return uq112x112(uint224(result)); } } } interface ITreasury { function deposit( uint _amount, address _token, uint _profit ) external returns ( bool ); function valueOf( address _token, uint _amount ) external view returns ( uint value_ ); } interface IBondCalculator { function valuation( address _LP, uint _amount ) external view returns ( uint ); function markdown( address _LP ) external view returns ( uint ); } interface IStaking { function stake( uint _amount, address _recipient ) external returns ( bool ); } interface IStakingHelper { function stake( uint _amount, address _recipient ) external; } contract OlympusBondDepository is Ownable { using FixedPoint for *; using SafeERC20 for IERC20; using SafeMath for uint; /* ======== EVENTS ======== */ event BondCreated( uint deposit, uint indexed payout, uint indexed expires, uint indexed priceInUSD ); event BondRedeemed( address indexed recipient, uint payout, uint remaining ); event BondPriceChanged( uint indexed priceInUSD, uint indexed internalPrice, uint indexed debtRatio ); event ControlVariableAdjustment( uint initialBCV, uint newBCV, uint adjustment, bool addition ); /* ======== STATE VARIABLES ======== */ address public immutable OHM; // token given as payment for bond address public immutable principle; // token used to create bond address public immutable treasury; // mints OHM when receives principle address public immutable DAO; // receives profit share from bond address public immutable bondCalculator; // calculates value of LP tokens address public staking; // to auto-stake payout address public stakingHelper; // to stake and claim if no staking warmup bool public useHelper; Terms public terms; // stores terms for new bonds Adjust public adjustment; // stores adjustment to BCV data mapping( address => Bond ) public bondInfo; // stores bond information for depositors uint public totalDebt; // total value of outstanding bonds; used for pricing uint public lastDecay; // reference block for debt decay /* ======== STRUCTS ======== */ // Info for creating new bonds struct Terms { uint controlVariable; // scaling variable for price uint vestingTerm; // in blocks uint minimumPrice; // vs principle value uint maxPayout; // in thousandths of a %. i.e. 500 = 0.5% uint fee; // as % of bond payout, in hundreths. ( 500 = 5% = 0.05 for every 1 paid) uint maxDebt; // 9 decimal debt ratio, max % total supply created as debt } // Info for bond holder struct Bond { uint payout; // OHM remaining to be paid uint vesting; // Blocks left to vest uint lastBlock; // Last interaction uint pricePaid; // In DAI, for front end viewing } // Info for incremental adjustments to control variable struct Adjust { bool add; // addition or subtraction uint rate; // increment uint target; // BCV when adjustment finished uint buffer; // minimum length (in blocks) between adjustments uint lastBlock; // block when last adjustment made } /* ======== INITIALIZATION ======== */ constructor ( address _OHM, address _principle, address _treasury, address _DAO, address _bondCalculator ) { require( _OHM != address(0) ); OHM = _OHM; require( _principle != address(0) ); principle = _principle; require( _treasury != address(0) ); treasury = _treasury; require( _DAO != address(0) ); DAO = _DAO; bondCalculator = _bondCalculator; } /** * @notice initializes bond parameters * @param _controlVariable uint * @param _vestingTerm uint * @param _minimumPrice uint * @param _maxPayout uint * @param _fee uint * @param _maxDebt uint * @param _initialDebt uint */ function initializeBondTerms( uint _controlVariable, uint _vestingTerm, uint _minimumPrice, uint _maxPayout, uint _fee, uint _maxDebt, uint _initialDebt ) external onlyPolicy() { require( terms.controlVariable == 0, "Bonds must be initialized from 0" ); terms = Terms ({ controlVariable: _controlVariable, vestingTerm: _vestingTerm, minimumPrice: _minimumPrice, maxPayout: _maxPayout, fee: _fee, maxDebt: _maxDebt }); totalDebt = _initialDebt; lastDecay = block.number; } /* ======== POLICY FUNCTIONS ======== */ enum PARAMETER { VESTING, PAYOUT, FEE, DEBT } /** * @notice set parameters for new bonds * @param _parameter PARAMETER * @param _input uint */ function setBondTerms ( PARAMETER _parameter, uint _input ) external onlyPolicy() { if ( _parameter == PARAMETER.VESTING ) { // 0 require( _input >= 10000, "Vesting must be longer than 36 hours" ); terms.vestingTerm = _input; } else if ( _parameter == PARAMETER.PAYOUT ) { // 1 require( _input <= 1000, "Payout cannot be above 1 percent" ); terms.maxPayout = _input; } else if ( _parameter == PARAMETER.FEE ) { // 2 require( _input <= 10000, "DAO fee cannot exceed payout" ); terms.fee = _input; } else if ( _parameter == PARAMETER.DEBT ) { // 3 terms.maxDebt = _input; } } /** * @notice set control variable adjustment * @param _addition bool * @param _increment uint * @param _target uint * @param _buffer uint */ function setAdjustment ( bool _addition, uint _increment, uint _target, uint _buffer ) external onlyPolicy() { require( _increment <= terms.controlVariable.mul( 25 ).div( 1000 ), "Increment too large" ); adjustment = Adjust({ add: _addition, rate: _increment, target: _target, buffer: _buffer, lastBlock: block.number }); } /** * @notice set contract for auto stake * @param _staking address * @param _helper bool */ function setStaking( address _staking, bool _helper ) external onlyPolicy() { require( _staking != address(0) ); if ( _helper ) { useHelper = true; stakingHelper = _staking; } else { useHelper = false; staking = _staking; } } /* ======== USER FUNCTIONS ======== */ /** * @notice deposit bond * @param _amount uint * @param _maxPrice uint * @param _depositor address * @return uint */ function deposit( uint _amount, uint _maxPrice, address _depositor ) external returns ( uint ) { require( _depositor != address(0), "Invalid address" ); decayDebt(); require( totalDebt <= terms.maxDebt, "Max capacity reached" ); uint priceInUSD = bondPriceInUSD(); // Stored in bond info uint nativePrice = _bondPrice(); require( _maxPrice >= nativePrice, "Slippage limit: more than max price" ); // slippage protection uint value = ITreasury( treasury ).valueOf( principle, _amount ); uint payout = payoutFor( value ); // payout to bonder is computed require( payout >= 100000, "Bond too small" ); // must be > 0.0001 OHM ( underflow protection ) require( payout <= maxPayout(), "Bond too large"); // size protection because there is no slippage // profits are calculated uint fee = payout.mul( terms.fee ).div( 10000 ); uint profit = value.sub( payout ).sub( fee ); /** principle is transferred in approved and deposited into the treasury, returning (_amount - profit) OHM */ IERC20( principle ).safeTransferFrom( msg.sender, address(this), _amount ); IERC20( principle ).approve( address( treasury ), _amount ); ITreasury( treasury ).deposit( _amount, principle, profit ); if ( fee != 0 ) { // fee is transferred to dao IERC20( OHM ).safeTransfer( DAO, fee ); } // total debt is increased totalDebt = totalDebt.add( value ); // depositor info is stored bondInfo[ _depositor ] = Bond({ payout: bondInfo[ _depositor ].payout.add( payout ), vesting: terms.vestingTerm, lastBlock: block.number, pricePaid: priceInUSD }); // indexed events are emitted emit BondCreated( _amount, payout, block.number.add( terms.vestingTerm ), priceInUSD ); emit BondPriceChanged( bondPriceInUSD(), _bondPrice(), debtRatio() ); adjust(); // control variable is adjusted return payout; } /** * @notice redeem bond for user * @param _recipient address * @param _stake bool * @return uint */ function redeem( address _recipient, bool _stake ) external returns ( uint ) { Bond memory info = bondInfo[ _recipient ]; uint percentVested = percentVestedFor( _recipient ); // (blocks since last interaction / vesting term remaining) if ( percentVested >= 10000 ) { // if fully vested delete bondInfo[ _recipient ]; // delete user info emit BondRedeemed( _recipient, info.payout, 0 ); // emit bond data return stakeOrSend( _recipient, _stake, info.payout ); // pay user everything due } else { // if unfinished // calculate payout vested uint payout = info.payout.mul( percentVested ).div( 10000 ); // store updated deposit info bondInfo[ _recipient ] = Bond({ payout: info.payout.sub( payout ), vesting: info.vesting.sub( block.number.sub( info.lastBlock ) ), lastBlock: block.number, pricePaid: info.pricePaid }); emit BondRedeemed( _recipient, payout, bondInfo[ _recipient ].payout ); return stakeOrSend( _recipient, _stake, payout ); } } /* ======== INTERNAL HELPER FUNCTIONS ======== */ /** * @notice allow user to stake payout automatically * @param _stake bool * @param _amount uint * @return uint */ function stakeOrSend( address _recipient, bool _stake, uint _amount ) internal returns ( uint ) { if ( !_stake ) { // if user does not want to stake IERC20( OHM ).transfer( _recipient, _amount ); // send payout } else { // if user wants to stake if ( useHelper ) { // use if staking warmup is 0 IERC20( OHM ).approve( stakingHelper, _amount ); IStakingHelper( stakingHelper ).stake( _amount, _recipient ); } else { IERC20( OHM ).approve( staking, _amount ); IStaking( staking ).stake( _amount, _recipient ); } } return _amount; } /** * @notice makes incremental adjustment to control variable */ function adjust() internal { uint blockCanAdjust = adjustment.lastBlock.add( adjustment.buffer ); if( adjustment.rate != 0 && block.number >= blockCanAdjust ) { uint initial = terms.controlVariable; if ( adjustment.add ) { terms.controlVariable = terms.controlVariable.add( adjustment.rate ); if ( terms.controlVariable >= adjustment.target ) { adjustment.rate = 0; } } else { terms.controlVariable = terms.controlVariable.sub( adjustment.rate ); if ( terms.controlVariable <= adjustment.target ) { adjustment.rate = 0; } } adjustment.lastBlock = block.number; emit ControlVariableAdjustment( initial, terms.controlVariable, adjustment.rate, adjustment.add ); } } /** * @notice reduce total debt */ function decayDebt() internal { totalDebt = totalDebt.sub( debtDecay() ); lastDecay = block.number; } /* ======== VIEW FUNCTIONS ======== */ /** * @notice determine maximum bond size * @return uint */ function maxPayout() public view returns ( uint ) { return IERC20( OHM ).totalSupply().mul( terms.maxPayout ).div( 100000 ); } /** * @notice calculate interest due for new bond * @param _value uint * @return uint */ function payoutFor( uint _value ) public view returns ( uint ) { return FixedPoint.fraction( _value, bondPrice() ).decode112with18().div( 1e16 ); } /** * @notice calculate current bond premium * @return price_ uint */ function bondPrice() public view returns ( uint price_ ) { price_ = terms.controlVariable.mul( debtRatio() ).add( 1000000000 ).div( 1e7 ); if ( price_ < terms.minimumPrice ) { price_ = terms.minimumPrice; } } /** * @notice calculate current bond price and remove floor if above * @return price_ uint */ function _bondPrice() internal returns ( uint price_ ) { price_ = terms.controlVariable.mul( debtRatio() ).add( 1000000000 ).div( 1e7 ); if ( price_ < terms.minimumPrice ) { price_ = terms.minimumPrice; } else if ( terms.minimumPrice != 0 ) { terms.minimumPrice = 0; } } /** * @notice converts bond price to DAI value * @return price_ uint */ function bondPriceInUSD() public view returns ( uint price_ ) { price_ = bondPrice().mul( IBondCalculator( bondCalculator ).markdown( principle ) ).div( 100 ); } /** * @notice calculate current ratio of debt to OHM supply * @return debtRatio_ uint */ function debtRatio() public view returns ( uint debtRatio_ ) { uint supply = IERC20( OHM ).totalSupply(); debtRatio_ = FixedPoint.fraction( currentDebt().mul( 1e9 ), supply ).decode112with18().div( 1e18 ); } /** * @notice debt ratio in same terms for reserve or liquidity bonds * @return uint */ function standardizedDebtRatio() external view returns ( uint ) { return debtRatio().mul( IBondCalculator( bondCalculator ).markdown( principle ) ).div( 1e9 ); } /** * @notice calculate debt factoring in decay * @return uint */ function currentDebt() public view returns ( uint ) { return totalDebt.sub( debtDecay() ); } /** * @notice amount to decay total debt by * @return decay_ uint */ function debtDecay() public view returns ( uint decay_ ) { uint blocksSinceLast = block.number.sub( lastDecay ); decay_ = totalDebt.mul( blocksSinceLast ).div( terms.vestingTerm ); if ( decay_ > totalDebt ) { decay_ = totalDebt; } } /** * @notice calculate how far into vesting a depositor is * @param _depositor address * @return percentVested_ uint */ function percentVestedFor( address _depositor ) public view returns ( uint percentVested_ ) { Bond memory bond = bondInfo[ _depositor ]; uint blocksSinceLast = block.number.sub( bond.lastBlock ); uint vesting = bond.vesting; if ( vesting > 0 ) { percentVested_ = blocksSinceLast.mul( 10000 ).div( vesting ); } else { percentVested_ = 0; } } /** * @notice calculate amount of OHM available for claim by depositor * @param _depositor address * @return pendingPayout_ uint */ function pendingPayoutFor( address _depositor ) external view returns ( uint pendingPayout_ ) { uint percentVested = percentVestedFor( _depositor ); uint payout = bondInfo[ _depositor ].payout; if ( percentVested >= 10000 ) { pendingPayout_ = payout; } else { pendingPayout_ = payout.mul( percentVested ).div( 10000 ); } } /* ======= AUXILLIARY ======= */ /** * @notice allow anyone to send lost tokens (excluding principle or OHM) to the DAO * @return bool */ function recoverLostToken( address _token ) external returns ( bool ) { require( _token != OHM ); require( _token != principle ); IERC20( _token ).safeTransfer( DAO, IERC20( _token ).balanceOf( address(this) ) ); return true; } }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_OHM","type":"address"},{"internalType":"address","name":"_principle","type":"address"},{"internalType":"address","name":"_treasury","type":"address"},{"internalType":"address","name":"_DAO","type":"address"},{"internalType":"address","name":"_bondCalculator","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"deposit","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"payout","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"expires","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"priceInUSD","type":"uint256"}],"name":"BondCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"priceInUSD","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"internalPrice","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"debtRatio","type":"uint256"}],"name":"BondPriceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"payout","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"remaining","type":"uint256"}],"name":"BondRedeemed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"initialBCV","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBCV","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"adjustment","type":"uint256"},{"indexed":false,"internalType":"bool","name":"addition","type":"bool"}],"name":"ControlVariableAdjustment","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipPulled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipPushed","type":"event"},{"inputs":[],"name":"DAO","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OHM","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"adjustment","outputs":[{"internalType":"bool","name":"add","type":"bool"},{"internalType":"uint256","name":"rate","type":"uint256"},{"internalType":"uint256","name":"target","type":"uint256"},{"internalType":"uint256","name":"buffer","type":"uint256"},{"internalType":"uint256","name":"lastBlock","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bondCalculator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"bondInfo","outputs":[{"internalType":"uint256","name":"payout","type":"uint256"},{"internalType":"uint256","name":"vesting","type":"uint256"},{"internalType":"uint256","name":"lastBlock","type":"uint256"},{"internalType":"uint256","name":"pricePaid","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bondPrice","outputs":[{"internalType":"uint256","name":"price_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bondPriceInUSD","outputs":[{"internalType":"uint256","name":"price_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"debtDecay","outputs":[{"internalType":"uint256","name":"decay_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"debtRatio","outputs":[{"internalType":"uint256","name":"debtRatio_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_maxPrice","type":"uint256"},{"internalType":"address","name":"_depositor","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_controlVariable","type":"uint256"},{"internalType":"uint256","name":"_vestingTerm","type":"uint256"},{"internalType":"uint256","name":"_minimumPrice","type":"uint256"},{"internalType":"uint256","name":"_maxPayout","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"uint256","name":"_maxDebt","type":"uint256"},{"internalType":"uint256","name":"_initialDebt","type":"uint256"}],"name":"initializeBondTerms","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastDecay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPayout","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"payoutFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_depositor","type":"address"}],"name":"pendingPayoutFor","outputs":[{"internalType":"uint256","name":"pendingPayout_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_depositor","type":"address"}],"name":"percentVestedFor","outputs":[{"internalType":"uint256","name":"percentVested_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"policy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"principle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pullManagement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner_","type":"address"}],"name":"pushManagement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"recoverLostToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"bool","name":"_stake","type":"bool"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceManagement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_addition","type":"bool"},{"internalType":"uint256","name":"_increment","type":"uint256"},{"internalType":"uint256","name":"_target","type":"uint256"},{"internalType":"uint256","name":"_buffer","type":"uint256"}],"name":"setAdjustment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum OlympusBondDepository.PARAMETER","name":"_parameter","type":"uint8"},{"internalType":"uint256","name":"_input","type":"uint256"}],"name":"setBondTerms","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_staking","type":"address"},{"internalType":"bool","name":"_helper","type":"bool"}],"name":"setStaking","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"staking","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingHelper","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"standardizedDebtRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"terms","outputs":[{"internalType":"uint256","name":"controlVariable","type":"uint256"},{"internalType":"uint256","name":"vestingTerm","type":"uint256"},{"internalType":"uint256","name":"minimumPrice","type":"uint256"},{"internalType":"uint256","name":"maxPayout","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"maxDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"useHelper","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6101206040523480156200001257600080fd5b506040516200448538038062004485833981810160405260a08110156200003857600080fd5b810190808051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a3600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614156200016757600080fd5b8473ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415620001d957600080fd5b8373ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156200024b57600080fd5b8273ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415620002bd57600080fd5b8173ffffffffffffffffffffffffffffffffffffffff1660e08173ffffffffffffffffffffffffffffffffffffffff1660601b815250508073ffffffffffffffffffffffffffffffffffffffff166101008173ffffffffffffffffffffffffffffffffffffffff1660601b81525050505050505060805160601c60a05160601c60c05160601c60e05160601c6101005160601c61409c620003e960003980611b095280612453528061274f525080612231528061255e528061265d5250806118965280611db05280612080528061213152508061097c5280611b455280611dec5280611ffd5280612044528061216e528061248f5280612601525080612253528061258252806125a852806127a65280612afe5280612cff5280612de65280612f85525061409c6000f3fe608060405234801561001057600080fd5b50600436106102065760003560e01c80637927ebf81161011a578063cd1234b3116100ad578063d7ccfb0b1161007c578063d7ccfb0b146108e4578063e0176de814610902578063e392a26214610920578063f5c2ab5b1461093e578063fc7b9c181461095c57610206565b8063cd1234b3146107c8578063cea55f5714610835578063d4d863ce14610853578063d5025625146108a357610206565b806398fabd3a116100e957806398fabd3a146106d2578063a6c41fec14610706578063b4abccba1461073a578063c5332b7c1461079457610206565b80637927ebf8146105e8578063844b5c7c1461062a5780638dbdbe6d14610648578063904b3ece146106b457610206565b8063451ee4a11161019d5780635a96ac0a1161016c5780635a96ac0a146104ee57806361d027b3146104f8578063715350081461052c578063759076e51461059657806377b81895146105b457610206565b8063451ee4a1146103e257806346f68ee91461041e5780634cf088d914610462578063507930ec1461049657610206565b80631a3d0068116101d95780631a3d0068146102d55780631e321a0f146103235780631feed31f1461035e5780632f3f470a146103c257610206565b8063016a42841461020b57806301b88ee81461023f5780630505c8c914610297578063089208d8146102cb575b600080fd5b61021361097a565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102816004803603602081101561025557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061099e565b6040518082815260200191505060405180910390f35b61029f610a35565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102d3610a5e565b005b610321600480360360808110156102eb57600080fd5b81019080803515159060200190929190803590602001909291908035906020019092919080359060200190929190505050610bdd565b005b61035c6004803603604081101561033957600080fd5b81019080803560ff16906020019092919080359060200190929190505050610dbc565b005b6103ac6004803603604081101561037457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050611081565b6040518082815260200191505060405180910390f35b6103ca611399565b60405180821515815260200191505060405180910390f35b6103ea6113ac565b6040518086151581526020018581526020018481526020018381526020018281526020019550505050505060405180910390f35b6104606004803603602081101561043457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506113dd565b005b61046a6115e2565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104d8600480360360208110156104ac57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611608565b6040518082815260200191505060405180910390f35b6104f66116ee565b005b610500611894565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610594600480360360e081101561054257600080fd5b81019080803590602001909291908035906020019092919080359060200190929190803590602001909291908035906020019092919080359060200190929190803590602001909291905050506118b8565b005b61059e611a79565b6040518082815260200191505060405180910390f35b6105bc611a9c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610614600480360360208110156105fe57600080fd5b8101908080359060200190929190505050611ac2565b6040518082815260200191505060405180910390f35b610632611afd565b6040518082815260200191505060405180910390f35b61069e6004803603606081101561065e57600080fd5b810190808035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611c12565b6040518082815260200191505060405180910390f35b6106bc612444565b6040518082815260200191505060405180910390f35b6106da61255c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61070e612580565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61077c6004803603602081101561075057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506125a4565b60405180821515815260200191505060405180910390f35b61079c61274d565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61080a600480360360208110156107de57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612771565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b61083d6127a1565b6040518082815260200191505060405180910390f35b6108a16004803603604081101561086957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050612896565b005b6108ab612a59565b60405180878152602001868152602001858152602001848152602001838152602001828152602001965050505050505060405180910390f35b6108ec612a83565b6040518082815260200191505060405180910390f35b61090a612aea565b6040518082815260200191505060405180910390f35b610928612bbe565b6040518082815260200191505060405180910390f35b610946612c1a565b6040518082815260200191505060405180910390f35b610964612c20565b6040518082815260200191505060405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806109aa83611608565b90506000600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015490506127108210610a0457809250610a2e565b610a2b612710610a1d8484612c2690919063ffffffff16565b612cac90919063ffffffff16565b92505b5050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b1f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610c9e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b610ccb6103e8610cbd6019600460000154612c2690919063ffffffff16565b612cac90919063ffffffff16565b831115610d40576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e6372656d656e7420746f6f206c617267650000000000000000000000000081525060200191505060405180910390fd5b6040518060a00160405280851515815260200184815260200183815260200182815260200143815250600a60008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020155606082015181600301556080820151816004015590505050505050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610e7d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60006003811115610e8a57fe5b826003811115610e9657fe5b1415610f0657612710811015610ef7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806140196024913960400191505060405180910390fd5b8060046001018190555061107d565b60016003811115610f1357fe5b826003811115610f1f57fe5b1415610fac576103e8811115610f9d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5061796f75742063616e6e6f742062652061626f766520312070657263656e7481525060200191505060405180910390fd5b8060046003018190555061107c565b60026003811115610fb957fe5b826003811115610fc557fe5b141561105157612710811115611043576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f44414f206665652063616e6e6f7420657863656564207061796f75740000000081525060200191505060405180910390fd5b80600480018190555061107b565b60038081111561105d57fe5b82600381111561106957fe5b141561107a57806004600501819055505b5b5b5b5050565b600061108b613f0d565b600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060800160405290816000820154815260200160018201548152602001600282015481526020016003820154815250509050600061110a85611608565b905061271081106111ea57600f60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008082016000905560018201600090556002820160009055600382016000905550508473ffffffffffffffffffffffffffffffffffffffff167f51c99f515c87b0d95ba97f616edd182e8f161c4932eac17c6fefe9dab58b77b183600001516000604051808381526020018281526020019250505060405180910390a26111e185858460000151612cf6565b92505050611393565b6000611217612710611209848660000151612c2690919063ffffffff16565b612cac90919063ffffffff16565b9050604051806080016040528061123b83866000015161314d90919063ffffffff16565b815260200161126d61125a86604001514361314d90919063ffffffff16565b866020015161314d90919063ffffffff16565b81526020014381526020018460600151815250600f60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301559050508573ffffffffffffffffffffffffffffffffffffffff167f51c99f515c87b0d95ba97f616edd182e8f161c4932eac17c6fefe9dab58b77b182600f60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154604051808381526020018281526020019250505060405180910390a261138d868683612cf6565b93505050505b92915050565b600360149054906101000a900460ff1681565b600a8060000160009054906101000a900460ff16908060010154908060020154908060030154908060040154905085565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461149e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611524576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613f676026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611612613f0d565b600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060800160405290816000820154815260200160018201548152602001600282015481526020016003820154815250509050600061169f82604001514361314d90919063ffffffff16565b905060008260200151905060008111156116e1576116da816116cc61271085612c2690919063ffffffff16565b612cac90919063ffffffff16565b93506116e6565b600093505b505050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611794576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180613f8d6022913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d60405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611979576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000600460000154146119f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f426f6e6473206d75737420626520696e697469616c697a65642066726f6d203081525060200191505060405180910390fd5b6040518060c00160405280888152602001878152602001868152602001858152602001848152602001838152506004600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a08201518160050155905050806010819055504360118190555050505050505050565b6000611a97611a86612bbe565b60105461314d90919063ffffffff16565b905090565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611af6662386f26fc10000611ae8611ae385611ade612a83565b613197565b613478565b612cac90919063ffffffff16565b9050919050565b6000611c0d6064611bff7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166332da80a37f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611bae57600080fd5b505afa158015611bc2573d6000803e3d6000fd5b505050506040513d6020811015611bd857600080fd5b8101908080519060200190929190505050611bf1612a83565b612c2690919063ffffffff16565b612cac90919063ffffffff16565b905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611cb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f496e76616c69642061646472657373000000000000000000000000000000000081525060200191505060405180910390fd5b611cbe6134b4565b6004600501546010541115611d3b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4d6178206361706163697479207265616368656400000000000000000000000081525060200191505060405180910390fd5b6000611d45611afd565b90506000611d516134df565b905080851015611dac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180613ff66023913960400191505060405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16631eec5a9a7f0000000000000000000000000000000000000000000000000000000000000000896040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060206040518083038186803b158015611e5d57600080fd5b505afa158015611e71573d6000803e3d6000fd5b505050506040513d6020811015611e8757600080fd5b810190808051906020019092919050505090506000611ea582611ac2565b9050620186a0811015611f20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f426f6e6420746f6f20736d616c6c00000000000000000000000000000000000081525060200191505060405180910390fd5b611f28612aea565b811115611f9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f426f6e6420746f6f206c6172676500000000000000000000000000000000000081525060200191505060405180910390fd5b6000611fca612710611fbc600480015485612c2690919063ffffffff16565b612cac90919063ffffffff16565b90506000611ff382611fe5858761314d90919063ffffffff16565b61314d90919063ffffffff16565b905061204233308c7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16613564909392919063ffffffff16565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b37f00000000000000000000000000000000000000000000000000000000000000008c6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156120f357600080fd5b505af1158015612107573d6000803e3d6000fd5b505050506040513d602081101561211d57600080fd5b8101908080519060200190929190505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663bc157ac18b7f0000000000000000000000000000000000000000000000000000000000000000846040518463ffffffff1660e01b8152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1580156121e857600080fd5b505af11580156121fc573d6000803e3d6000fd5b505050506040513d602081101561221257600080fd5b81019080805190602001909291905050505060008214612298576122977f0000000000000000000000000000000000000000000000000000000000000000837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166136259092919063ffffffff16565b5b6122ad846010546136c790919063ffffffff16565b601081905550604051806080016040528061231385600f60008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001546136c790919063ffffffff16565b8152602001600460010154815260200143815260200187815250600f60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030155905050856123b0600460010154436136c790919063ffffffff16565b847f1fec6dc81f140574bf43f6b1e420ae1dd47928b9d57db8cbd7b8611063b85ae58d6040518082815260200191505060405180910390a46123f06127a1565b6123f86134df565b612400611afd565b7f375b221f40939bfd8f49723a17cf7bc6d576ebf72efe2cc3e991826f5b3f390a60405160405180910390a461243461374f565b8296505050505050509392505050565b6000612557633b9aca006125497f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166332da80a37f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156124f857600080fd5b505afa15801561250c573d6000803e3d6000fd5b505050506040513d602081101561252257600080fd5b810190808051906020019092919050505061253b6127a1565b612c2690919063ffffffff16565b612cac90919063ffffffff16565b905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156125ff57600080fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561265857600080fd5b6127447f00000000000000000000000000000000000000000000000000000000000000008373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156126e357600080fd5b505afa1580156126f7573d6000803e3d6000fd5b505050506040513d602081101561270d57600080fd5b81019080805190602001909291905050508473ffffffffffffffffffffffffffffffffffffffff166136259092919063ffffffff16565b60019050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600f6020528060005260406000206000915090508060000154908060010154908060020154908060030154905084565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561280a57600080fd5b505afa15801561281e573d6000803e3d6000fd5b505050506040513d602081101561283457600080fd5b81019080805190602001909291905050509050612890670de0b6b3a764000061288261287d612877633b9aca00612869611a79565b612c2690919063ffffffff16565b85613197565b613478565b612cac90919063ffffffff16565b91505090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612957576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561299157600080fd5b80156129f8576001600360146101000a81548160ff02191690831515021790555081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612a55565b6000600360146101000a81548160ff02191690831515021790555081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5050565b60048060000154908060010154908060020154908060030154908060040154908060050154905086565b6000612acf62989680612ac1633b9aca00612ab3612a9f6127a1565b600460000154612c2690919063ffffffff16565b6136c790919063ffffffff16565b612cac90919063ffffffff16565b9050600460020154811015612ae75760046002015490505b90565b6000612bb9620186a0612bab6004600301547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612b6257600080fd5b505afa158015612b76573d6000803e3d6000fd5b505050506040513d6020811015612b8c57600080fd5b8101908080519060200190929190505050612c2690919063ffffffff16565b612cac90919063ffffffff16565b905090565b600080612bd66011544361314d90919063ffffffff16565b9050612c04600460010154612bf683601054612c2690919063ffffffff16565b612cac90919063ffffffff16565b9150601054821115612c165760105491505b5090565b60115481565b60105481565b600080831415612c395760009050612ca6565b6000828402905082848281612c4a57fe5b0414612ca1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180613fd56021913960400191505060405180910390fd5b809150505b92915050565b6000612cee83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506138b5565b905092915050565b600082612dcf577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612d8e57600080fd5b505af1158015612da2573d6000803e3d6000fd5b505050506040513d6020811015612db857600080fd5b810190808051906020019092919050505050613143565b600360149054906101000a900460ff1615612f83577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612e9757600080fd5b505af1158015612eab573d6000803e3d6000fd5b505050506040513d6020811015612ec157600080fd5b810190808051906020019092919050505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637acb775783866040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b158015612f6657600080fd5b505af1158015612f7a573d6000803e3d6000fd5b50505050613142565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561303657600080fd5b505af115801561304a573d6000803e3d6000fd5b505050506040513d602081101561306057600080fd5b810190808051906020019092919050505050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637acb775783866040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b15801561310557600080fd5b505af1158015613119573d6000803e3d6000fd5b505050506040513d602081101561312f57600080fd5b8101908080519060200190929190505050505b5b8190509392505050565b600061318f83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061397b565b905092915050565b61319f613f35565b600082116131f8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613faf6026913960400191505060405180910390fd5b600083141561323657604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509050613472565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff71ffffffffffffffffffffffffffffffffffff16831161336f57600082607060ff1685901b8161328357fe5b0490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681111561333a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815250915050613472565b600061338b846e01000000000000000000000000000085613a3b565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16811115613441576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509150505b92915050565b60006612725dd1d243ab82600001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16816134ac57fe5b049050919050565b6134d06134bf612bbe565b60105461314d90919063ffffffff16565b60108190555043601181905550565b600061352b6298968061351d633b9aca0061350f6134fb6127a1565b600460000154612c2690919063ffffffff16565b6136c790919063ffffffff16565b612cac90919063ffffffff16565b9050600460020154811015613547576004600201549050613561565b6000600460020154146135605760006004600201819055505b5b90565b61361f846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613afd565b50505050565b6136c28363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613afd565b505050565b600080828401905083811015613745576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600061376e600a60030154600a600401546136c790919063ffffffff16565b90506000600a60010154141580156137865750804310155b156138b25760006004600001549050600a60000160009054906101000a900460ff16156137f5576137ca600a600101546004600001546136c790919063ffffffff16565b600460000181905550600a60020154600460000154106137f0576000600a600101819055505b613839565b613812600a6001015460046000015461314d90919063ffffffff16565b600460000181905550600a6002015460046000015411613838576000600a600101819055505b5b43600a600401819055507fb923e581a0f83128e9e1d8297aa52b18d6744310476e0b54509c054cd7a93b2a81600460000154600a60010154600a60000160009054906101000a900460ff1660405180858152602001848152602001838152602001821515815260200194505050505060405180910390a1505b50565b60008083118290613961576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561392657808201518184015260208101905061390b565b50505050905090810190601f1680156139535780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161396d57fe5b049050809150509392505050565b6000838311158290613a28576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156139ed5780820151818401526020810190506139d2565b50505050905090810190601f168015613a1a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b6000806000613a4a8686613bec565b9150915060008480613a5857fe5b868809905082811115613a6c576001820391505b8083039250848210613ae6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f46756c6c4d6174683a3a6d756c4469763a206f766572666c6f7700000000000081525060200191505060405180910390fd5b613af1838387613c3f565b93505050509392505050565b6060613b5f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613cdc9092919063ffffffff16565b9050600081511115613be757808060200190516020811015613b8057600080fd5b8101908080519060200190929190505050613be6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a81526020018061403d602a913960400191505060405180910390fd5b5b505050565b60008060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80613c1957fe5b84860990508385029250828103915082811015613c37576001820391505b509250929050565b6000808260000383169050808381613c5357fe5b049250808581613c5f57fe5b0494506001818260000381613c7057fe5b04018402850194506000600190508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808602925050509392505050565b6060613ceb8484600085613cf4565b90509392505050565b6060613cff85613efa565b613d71576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310613dc15780518252602082019150602081019050602083039250613d9e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613e23576040519150601f19603f3d011682016040523d82523d6000602084013e613e28565b606091505b50915091508115613e3d578092505050613ef2565b600081511115613e505780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613eb7578082015181840152602081019050613e9c565b50505050905090810190601f168015613ee45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b949350505050565b600080823b905060008111915050919050565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6c4669786564506f696e743a3a6672616374696f6e3a206469766973696f6e206279207a65726f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77536c697070616765206c696d69743a206d6f7265207468616e206d617820707269636556657374696e67206d757374206265206c6f6e676572207468616e20333620686f7572735361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220fc857723db14db951add5c153775b70a97693215662ea6ad8ce2b8a44cdc18cb64736f6c6343000705003300000000000000000000000021ad647b8f4fe333212e735bfc1f36b4941e6ad2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000061d8a57b3919e9f4777c80b6cf1138962855d2ca00000000000000000000000042e61987a5cba002880b3cc5c800952a5804a1c5000000000000000000000000e6d9ba8b1da379a1b3b57033d87717c0db88f0d6
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102065760003560e01c80637927ebf81161011a578063cd1234b3116100ad578063d7ccfb0b1161007c578063d7ccfb0b146108e4578063e0176de814610902578063e392a26214610920578063f5c2ab5b1461093e578063fc7b9c181461095c57610206565b8063cd1234b3146107c8578063cea55f5714610835578063d4d863ce14610853578063d5025625146108a357610206565b806398fabd3a116100e957806398fabd3a146106d2578063a6c41fec14610706578063b4abccba1461073a578063c5332b7c1461079457610206565b80637927ebf8146105e8578063844b5c7c1461062a5780638dbdbe6d14610648578063904b3ece146106b457610206565b8063451ee4a11161019d5780635a96ac0a1161016c5780635a96ac0a146104ee57806361d027b3146104f8578063715350081461052c578063759076e51461059657806377b81895146105b457610206565b8063451ee4a1146103e257806346f68ee91461041e5780634cf088d914610462578063507930ec1461049657610206565b80631a3d0068116101d95780631a3d0068146102d55780631e321a0f146103235780631feed31f1461035e5780632f3f470a146103c257610206565b8063016a42841461020b57806301b88ee81461023f5780630505c8c914610297578063089208d8146102cb575b600080fd5b61021361097a565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102816004803603602081101561025557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061099e565b6040518082815260200191505060405180910390f35b61029f610a35565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102d3610a5e565b005b610321600480360360808110156102eb57600080fd5b81019080803515159060200190929190803590602001909291908035906020019092919080359060200190929190505050610bdd565b005b61035c6004803603604081101561033957600080fd5b81019080803560ff16906020019092919080359060200190929190505050610dbc565b005b6103ac6004803603604081101561037457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050611081565b6040518082815260200191505060405180910390f35b6103ca611399565b60405180821515815260200191505060405180910390f35b6103ea6113ac565b6040518086151581526020018581526020018481526020018381526020018281526020019550505050505060405180910390f35b6104606004803603602081101561043457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506113dd565b005b61046a6115e2565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104d8600480360360208110156104ac57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611608565b6040518082815260200191505060405180910390f35b6104f66116ee565b005b610500611894565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610594600480360360e081101561054257600080fd5b81019080803590602001909291908035906020019092919080359060200190929190803590602001909291908035906020019092919080359060200190929190803590602001909291905050506118b8565b005b61059e611a79565b6040518082815260200191505060405180910390f35b6105bc611a9c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610614600480360360208110156105fe57600080fd5b8101908080359060200190929190505050611ac2565b6040518082815260200191505060405180910390f35b610632611afd565b6040518082815260200191505060405180910390f35b61069e6004803603606081101561065e57600080fd5b810190808035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611c12565b6040518082815260200191505060405180910390f35b6106bc612444565b6040518082815260200191505060405180910390f35b6106da61255c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61070e612580565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61077c6004803603602081101561075057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506125a4565b60405180821515815260200191505060405180910390f35b61079c61274d565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61080a600480360360208110156107de57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612771565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b61083d6127a1565b6040518082815260200191505060405180910390f35b6108a16004803603604081101561086957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050612896565b005b6108ab612a59565b60405180878152602001868152602001858152602001848152602001838152602001828152602001965050505050505060405180910390f35b6108ec612a83565b6040518082815260200191505060405180910390f35b61090a612aea565b6040518082815260200191505060405180910390f35b610928612bbe565b6040518082815260200191505060405180910390f35b610946612c1a565b6040518082815260200191505060405180910390f35b610964612c20565b6040518082815260200191505060405180910390f35b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6000806109aa83611608565b90506000600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015490506127108210610a0457809250610a2e565b610a2b612710610a1d8484612c2690919063ffffffff16565b612cac90919063ffffffff16565b92505b5050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b1f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610c9e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b610ccb6103e8610cbd6019600460000154612c2690919063ffffffff16565b612cac90919063ffffffff16565b831115610d40576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e6372656d656e7420746f6f206c617267650000000000000000000000000081525060200191505060405180910390fd5b6040518060a00160405280851515815260200184815260200183815260200182815260200143815250600a60008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020155606082015181600301556080820151816004015590505050505050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610e7d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60006003811115610e8a57fe5b826003811115610e9657fe5b1415610f0657612710811015610ef7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806140196024913960400191505060405180910390fd5b8060046001018190555061107d565b60016003811115610f1357fe5b826003811115610f1f57fe5b1415610fac576103e8811115610f9d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5061796f75742063616e6e6f742062652061626f766520312070657263656e7481525060200191505060405180910390fd5b8060046003018190555061107c565b60026003811115610fb957fe5b826003811115610fc557fe5b141561105157612710811115611043576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f44414f206665652063616e6e6f7420657863656564207061796f75740000000081525060200191505060405180910390fd5b80600480018190555061107b565b60038081111561105d57fe5b82600381111561106957fe5b141561107a57806004600501819055505b5b5b5b5050565b600061108b613f0d565b600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060800160405290816000820154815260200160018201548152602001600282015481526020016003820154815250509050600061110a85611608565b905061271081106111ea57600f60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008082016000905560018201600090556002820160009055600382016000905550508473ffffffffffffffffffffffffffffffffffffffff167f51c99f515c87b0d95ba97f616edd182e8f161c4932eac17c6fefe9dab58b77b183600001516000604051808381526020018281526020019250505060405180910390a26111e185858460000151612cf6565b92505050611393565b6000611217612710611209848660000151612c2690919063ffffffff16565b612cac90919063ffffffff16565b9050604051806080016040528061123b83866000015161314d90919063ffffffff16565b815260200161126d61125a86604001514361314d90919063ffffffff16565b866020015161314d90919063ffffffff16565b81526020014381526020018460600151815250600f60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301559050508573ffffffffffffffffffffffffffffffffffffffff167f51c99f515c87b0d95ba97f616edd182e8f161c4932eac17c6fefe9dab58b77b182600f60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154604051808381526020018281526020019250505060405180910390a261138d868683612cf6565b93505050505b92915050565b600360149054906101000a900460ff1681565b600a8060000160009054906101000a900460ff16908060010154908060020154908060030154908060040154905085565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461149e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611524576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613f676026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611612613f0d565b600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060800160405290816000820154815260200160018201548152602001600282015481526020016003820154815250509050600061169f82604001514361314d90919063ffffffff16565b905060008260200151905060008111156116e1576116da816116cc61271085612c2690919063ffffffff16565b612cac90919063ffffffff16565b93506116e6565b600093505b505050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611794576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180613f8d6022913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d60405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b7f00000000000000000000000061d8a57b3919e9f4777c80b6cf1138962855d2ca81565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611979576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000600460000154146119f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f426f6e6473206d75737420626520696e697469616c697a65642066726f6d203081525060200191505060405180910390fd5b6040518060c00160405280888152602001878152602001868152602001858152602001848152602001838152506004600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a08201518160050155905050806010819055504360118190555050505050505050565b6000611a97611a86612bbe565b60105461314d90919063ffffffff16565b905090565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611af6662386f26fc10000611ae8611ae385611ade612a83565b613197565b613478565b612cac90919063ffffffff16565b9050919050565b6000611c0d6064611bff7f000000000000000000000000e6d9ba8b1da379a1b3b57033d87717c0db88f0d673ffffffffffffffffffffffffffffffffffffffff166332da80a37f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611bae57600080fd5b505afa158015611bc2573d6000803e3d6000fd5b505050506040513d6020811015611bd857600080fd5b8101908080519060200190929190505050611bf1612a83565b612c2690919063ffffffff16565b612cac90919063ffffffff16565b905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611cb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f496e76616c69642061646472657373000000000000000000000000000000000081525060200191505060405180910390fd5b611cbe6134b4565b6004600501546010541115611d3b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4d6178206361706163697479207265616368656400000000000000000000000081525060200191505060405180910390fd5b6000611d45611afd565b90506000611d516134df565b905080851015611dac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180613ff66023913960400191505060405180910390fd5b60007f00000000000000000000000061d8a57b3919e9f4777c80b6cf1138962855d2ca73ffffffffffffffffffffffffffffffffffffffff16631eec5a9a7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2896040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060206040518083038186803b158015611e5d57600080fd5b505afa158015611e71573d6000803e3d6000fd5b505050506040513d6020811015611e8757600080fd5b810190808051906020019092919050505090506000611ea582611ac2565b9050620186a0811015611f20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f426f6e6420746f6f20736d616c6c00000000000000000000000000000000000081525060200191505060405180910390fd5b611f28612aea565b811115611f9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f426f6e6420746f6f206c6172676500000000000000000000000000000000000081525060200191505060405180910390fd5b6000611fca612710611fbc600480015485612c2690919063ffffffff16565b612cac90919063ffffffff16565b90506000611ff382611fe5858761314d90919063ffffffff16565b61314d90919063ffffffff16565b905061204233308c7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff16613564909392919063ffffffff16565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663095ea7b37f00000000000000000000000061d8a57b3919e9f4777c80b6cf1138962855d2ca8c6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156120f357600080fd5b505af1158015612107573d6000803e3d6000fd5b505050506040513d602081101561211d57600080fd5b8101908080519060200190929190505050507f00000000000000000000000061d8a57b3919e9f4777c80b6cf1138962855d2ca73ffffffffffffffffffffffffffffffffffffffff1663bc157ac18b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2846040518463ffffffff1660e01b8152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1580156121e857600080fd5b505af11580156121fc573d6000803e3d6000fd5b505050506040513d602081101561221257600080fd5b81019080805190602001909291905050505060008214612298576122977f00000000000000000000000042e61987a5cba002880b3cc5c800952a5804a1c5837f00000000000000000000000021ad647b8f4fe333212e735bfc1f36b4941e6ad273ffffffffffffffffffffffffffffffffffffffff166136259092919063ffffffff16565b5b6122ad846010546136c790919063ffffffff16565b601081905550604051806080016040528061231385600f60008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001546136c790919063ffffffff16565b8152602001600460010154815260200143815260200187815250600f60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030155905050856123b0600460010154436136c790919063ffffffff16565b847f1fec6dc81f140574bf43f6b1e420ae1dd47928b9d57db8cbd7b8611063b85ae58d6040518082815260200191505060405180910390a46123f06127a1565b6123f86134df565b612400611afd565b7f375b221f40939bfd8f49723a17cf7bc6d576ebf72efe2cc3e991826f5b3f390a60405160405180910390a461243461374f565b8296505050505050509392505050565b6000612557633b9aca006125497f000000000000000000000000e6d9ba8b1da379a1b3b57033d87717c0db88f0d673ffffffffffffffffffffffffffffffffffffffff166332da80a37f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156124f857600080fd5b505afa15801561250c573d6000803e3d6000fd5b505050506040513d602081101561252257600080fd5b810190808051906020019092919050505061253b6127a1565b612c2690919063ffffffff16565b612cac90919063ffffffff16565b905090565b7f00000000000000000000000042e61987a5cba002880b3cc5c800952a5804a1c581565b7f00000000000000000000000021ad647b8f4fe333212e735bfc1f36b4941e6ad281565b60007f00000000000000000000000021ad647b8f4fe333212e735bfc1f36b4941e6ad273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156125ff57600080fd5b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561265857600080fd5b6127447f00000000000000000000000042e61987a5cba002880b3cc5c800952a5804a1c58373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156126e357600080fd5b505afa1580156126f7573d6000803e3d6000fd5b505050506040513d602081101561270d57600080fd5b81019080805190602001909291905050508473ffffffffffffffffffffffffffffffffffffffff166136259092919063ffffffff16565b60019050919050565b7f000000000000000000000000e6d9ba8b1da379a1b3b57033d87717c0db88f0d681565b600f6020528060005260406000206000915090508060000154908060010154908060020154908060030154905084565b6000807f00000000000000000000000021ad647b8f4fe333212e735bfc1f36b4941e6ad273ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561280a57600080fd5b505afa15801561281e573d6000803e3d6000fd5b505050506040513d602081101561283457600080fd5b81019080805190602001909291905050509050612890670de0b6b3a764000061288261287d612877633b9aca00612869611a79565b612c2690919063ffffffff16565b85613197565b613478565b612cac90919063ffffffff16565b91505090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612957576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561299157600080fd5b80156129f8576001600360146101000a81548160ff02191690831515021790555081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612a55565b6000600360146101000a81548160ff02191690831515021790555081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5050565b60048060000154908060010154908060020154908060030154908060040154908060050154905086565b6000612acf62989680612ac1633b9aca00612ab3612a9f6127a1565b600460000154612c2690919063ffffffff16565b6136c790919063ffffffff16565b612cac90919063ffffffff16565b9050600460020154811015612ae75760046002015490505b90565b6000612bb9620186a0612bab6004600301547f00000000000000000000000021ad647b8f4fe333212e735bfc1f36b4941e6ad273ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612b6257600080fd5b505afa158015612b76573d6000803e3d6000fd5b505050506040513d6020811015612b8c57600080fd5b8101908080519060200190929190505050612c2690919063ffffffff16565b612cac90919063ffffffff16565b905090565b600080612bd66011544361314d90919063ffffffff16565b9050612c04600460010154612bf683601054612c2690919063ffffffff16565b612cac90919063ffffffff16565b9150601054821115612c165760105491505b5090565b60115481565b60105481565b600080831415612c395760009050612ca6565b6000828402905082848281612c4a57fe5b0414612ca1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180613fd56021913960400191505060405180910390fd5b809150505b92915050565b6000612cee83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506138b5565b905092915050565b600082612dcf577f00000000000000000000000021ad647b8f4fe333212e735bfc1f36b4941e6ad273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612d8e57600080fd5b505af1158015612da2573d6000803e3d6000fd5b505050506040513d6020811015612db857600080fd5b810190808051906020019092919050505050613143565b600360149054906101000a900460ff1615612f83577f00000000000000000000000021ad647b8f4fe333212e735bfc1f36b4941e6ad273ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612e9757600080fd5b505af1158015612eab573d6000803e3d6000fd5b505050506040513d6020811015612ec157600080fd5b810190808051906020019092919050505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637acb775783866040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b158015612f6657600080fd5b505af1158015612f7a573d6000803e3d6000fd5b50505050613142565b7f00000000000000000000000021ad647b8f4fe333212e735bfc1f36b4941e6ad273ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561303657600080fd5b505af115801561304a573d6000803e3d6000fd5b505050506040513d602081101561306057600080fd5b810190808051906020019092919050505050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637acb775783866040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b15801561310557600080fd5b505af1158015613119573d6000803e3d6000fd5b505050506040513d602081101561312f57600080fd5b8101908080519060200190929190505050505b5b8190509392505050565b600061318f83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061397b565b905092915050565b61319f613f35565b600082116131f8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613faf6026913960400191505060405180910390fd5b600083141561323657604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509050613472565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff71ffffffffffffffffffffffffffffffffffff16831161336f57600082607060ff1685901b8161328357fe5b0490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681111561333a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815250915050613472565b600061338b846e01000000000000000000000000000085613a3b565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16811115613441576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509150505b92915050565b60006612725dd1d243ab82600001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16816134ac57fe5b049050919050565b6134d06134bf612bbe565b60105461314d90919063ffffffff16565b60108190555043601181905550565b600061352b6298968061351d633b9aca0061350f6134fb6127a1565b600460000154612c2690919063ffffffff16565b6136c790919063ffffffff16565b612cac90919063ffffffff16565b9050600460020154811015613547576004600201549050613561565b6000600460020154146135605760006004600201819055505b5b90565b61361f846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613afd565b50505050565b6136c28363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613afd565b505050565b600080828401905083811015613745576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600061376e600a60030154600a600401546136c790919063ffffffff16565b90506000600a60010154141580156137865750804310155b156138b25760006004600001549050600a60000160009054906101000a900460ff16156137f5576137ca600a600101546004600001546136c790919063ffffffff16565b600460000181905550600a60020154600460000154106137f0576000600a600101819055505b613839565b613812600a6001015460046000015461314d90919063ffffffff16565b600460000181905550600a6002015460046000015411613838576000600a600101819055505b5b43600a600401819055507fb923e581a0f83128e9e1d8297aa52b18d6744310476e0b54509c054cd7a93b2a81600460000154600a60010154600a60000160009054906101000a900460ff1660405180858152602001848152602001838152602001821515815260200194505050505060405180910390a1505b50565b60008083118290613961576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561392657808201518184015260208101905061390b565b50505050905090810190601f1680156139535780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161396d57fe5b049050809150509392505050565b6000838311158290613a28576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156139ed5780820151818401526020810190506139d2565b50505050905090810190601f168015613a1a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b6000806000613a4a8686613bec565b9150915060008480613a5857fe5b868809905082811115613a6c576001820391505b8083039250848210613ae6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f46756c6c4d6174683a3a6d756c4469763a206f766572666c6f7700000000000081525060200191505060405180910390fd5b613af1838387613c3f565b93505050509392505050565b6060613b5f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613cdc9092919063ffffffff16565b9050600081511115613be757808060200190516020811015613b8057600080fd5b8101908080519060200190929190505050613be6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a81526020018061403d602a913960400191505060405180910390fd5b5b505050565b60008060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80613c1957fe5b84860990508385029250828103915082811015613c37576001820391505b509250929050565b6000808260000383169050808381613c5357fe5b049250808581613c5f57fe5b0494506001818260000381613c7057fe5b04018402850194506000600190508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808602925050509392505050565b6060613ceb8484600085613cf4565b90509392505050565b6060613cff85613efa565b613d71576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310613dc15780518252602082019150602081019050602083039250613d9e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613e23576040519150601f19603f3d011682016040523d82523d6000602084013e613e28565b606091505b50915091508115613e3d578092505050613ef2565b600081511115613e505780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613eb7578082015181840152602081019050613e9c565b50505050905090810190601f168015613ee45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b949350505050565b600080823b905060008111915050919050565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6c4669786564506f696e743a3a6672616374696f6e3a206469766973696f6e206279207a65726f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77536c697070616765206c696d69743a206d6f7265207468616e206d617820707269636556657374696e67206d757374206265206c6f6e676572207468616e20333620686f7572735361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220fc857723db14db951add5c153775b70a97693215662ea6ad8ce2b8a44cdc18cb64736f6c63430007050033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000021ad647b8f4fe333212e735bfc1f36b4941e6ad2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000061d8a57b3919e9f4777c80b6cf1138962855d2ca00000000000000000000000042e61987a5cba002880b3cc5c800952a5804a1c5000000000000000000000000e6d9ba8b1da379a1b3b57033d87717c0db88f0d6
-----Decoded View---------------
Arg [0] : _OHM (address): 0x21ad647b8F4Fe333212e735bfC1F36B4941E6Ad2
Arg [1] : _principle (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [2] : _treasury (address): 0x61d8a57b3919e9F4777C80b6CF1138962855d2Ca
Arg [3] : _DAO (address): 0x42E61987A5CbA002880b3cc5c800952a5804a1C5
Arg [4] : _bondCalculator (address): 0xe6D9ba8B1Da379a1B3B57033d87717c0Db88F0D6
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 00000000000000000000000021ad647b8f4fe333212e735bfc1f36b4941e6ad2
Arg [1] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [2] : 00000000000000000000000061d8a57b3919e9f4777c80b6cf1138962855d2ca
Arg [3] : 00000000000000000000000042e61987a5cba002880b3cc5c800952a5804a1c5
Arg [4] : 000000000000000000000000e6d9ba8b1da379a1b3b57033d87717c0db88f0d6
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $2,255.55 | 0.1409 | $317.87 |
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.