Source Code
Latest 25 from a total of 4,067 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Initialize Bond ... | 3973952 | 1029 days ago | IN | 0 MOVR | 0.00015371 | ||||
| Initialize Bond ... | 1925480 | 1340 days ago | IN | 0 MOVR | 0.00006475 | ||||
| Set Bond Terms | 1925480 | 1340 days ago | IN | 0 MOVR | 0.00002096 | ||||
| Initialize Bond ... | 1914399 | 1342 days ago | IN | 0 MOVR | 0.00006475 | ||||
| Set Bond Terms | 1914399 | 1342 days ago | IN | 0 MOVR | 0.00002096 | ||||
| Initialize Bond ... | 1914315 | 1342 days ago | IN | 0 MOVR | 0.00006475 | ||||
| Set Bond Terms | 1914314 | 1342 days ago | IN | 0 MOVR | 0.00002096 | ||||
| Initialize Bond ... | 1914220 | 1342 days ago | IN | 0 MOVR | 0.00006475 | ||||
| Set Bond Terms | 1914220 | 1342 days ago | IN | 0 MOVR | 0.00002096 | ||||
| Initialize Bond ... | 1914135 | 1342 days ago | IN | 0 MOVR | 0.00006475 | ||||
| Set Bond Terms | 1914135 | 1342 days ago | IN | 0 MOVR | 0.00002096 | ||||
| Initialize Bond ... | 1914052 | 1342 days ago | IN | 0 MOVR | 0.00006475 | ||||
| Set Bond Terms | 1914052 | 1342 days ago | IN | 0 MOVR | 0.00002096 | ||||
| Initialize Bond ... | 1913966 | 1342 days ago | IN | 0 MOVR | 0.00006475 | ||||
| Set Bond Terms | 1913965 | 1342 days ago | IN | 0 MOVR | 0.00002096 | ||||
| Initialize Bond ... | 1913876 | 1342 days ago | IN | 0 MOVR | 0.00006475 | ||||
| Set Bond Terms | 1913875 | 1342 days ago | IN | 0 MOVR | 0.00002096 | ||||
| Initialize Bond ... | 1913792 | 1342 days ago | IN | 0 MOVR | 0.00006475 | ||||
| Set Bond Terms | 1913792 | 1342 days ago | IN | 0 MOVR | 0.00002096 | ||||
| Initialize Bond ... | 1913706 | 1342 days ago | IN | 0 MOVR | 0.00006475 | ||||
| Set Bond Terms | 1913706 | 1342 days ago | IN | 0 MOVR | 0.00002096 | ||||
| Initialize Bond ... | 1913618 | 1342 days ago | IN | 0 MOVR | 0.00006475 | ||||
| Set Bond Terms | 1913617 | 1342 days ago | IN | 0 MOVR | 0.00002096 | ||||
| Initialize Bond ... | 1913531 | 1342 days ago | IN | 0 MOVR | 0.00006475 | ||||
| Set Bond Terms | 1913530 | 1342 days ago | IN | 0 MOVR | 0.00002096 |
View more zero value Internal Transactions in Advanced View mode
Cross-Chain Transactions
Loading...
Loading
Contract Name:
FantohmBondStakingDepository
Compiler Version
v0.7.5+commit.eb77ed08
Optimization Enabled:
Yes 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 ( uint send_ );
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 IsFHM {
function balanceForGons( uint gons ) external view returns ( uint );
function gonsForBalance( uint amount ) external view returns ( uint );
}
interface IStaking {
function stake( uint _amount, address _recipient ) external returns ( bool );
function claim( address _recipient ) external;
}
interface IFHUDMinter {
function getMarketPrice() external view returns (uint);
}
interface IFHMCirculatingSupply {
function OHMCirculatingSupply() external view returns ( uint );
}
contract FantohmBondStakingDepository 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 FHM; // reward from treasury which is staked for the time of the bond
address public immutable sFHM; // token given as payment for bond
address public immutable principle; // token used to create bond
address public immutable treasury; // mints FHM when receives principle
address public immutable DAO; // receives profit share from bond
address public immutable fhudMinter; // FHUD minter
address public immutable fhmCirculatingSupply; // FHM circulating supply
bool public immutable isLiquidityBond; // LP and Reserve bonds are treated slightly different
address public immutable bondCalculator; // calculates value of LP tokens
address public staking; // to auto-stake payout
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 maximumDiscount; // in hundreds of a %, 500 = 5%
uint maxPayout; // in thousandths of a %. i.e. 500 = 0.5%
uint fee; // as % of bond payout, in hundreds. ( 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 gonsPayout; // sFHM remaining to be paid
uint fhmPayout; // FHM payout in time of creation
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 _FHM,
address _sFHM,
address _principle,
address _treasury,
address _DAO,
address _bondCalculator,
address _fhudMinter,
address _fhmCirculatingSupply
) {
require( _FHM != address(0) );
FHM = _FHM;
require( _sFHM != address(0) );
sFHM = _sFHM;
require( _principle != address(0) );
principle = _principle;
require( _treasury != address(0) );
treasury = _treasury;
require( _DAO != address(0) );
DAO = _DAO;
require( _fhudMinter != address(0) );
fhudMinter = _fhudMinter;
require( _fhmCirculatingSupply != address(0) );
fhmCirculatingSupply = _fhmCirculatingSupply;
// bondCalculator should be address(0) if not LP bond
bondCalculator = _bondCalculator;
isLiquidityBond = ( _bondCalculator != address(0) );
}
/**
* @notice initializes bond parameters
* @param _controlVariable uint
* @param _vestingTerm uint
* @param _minimumPrice uint
* @param _maximumDiscount uint
* @param _maxPayout uint
* @param _fee uint
* @param _maxDebt uint
* @param _initialDebt uint
*/
function initializeBondTerms(
uint _controlVariable,
uint _vestingTerm,
uint _minimumPrice,
uint _maximumDiscount,
uint _maxPayout,
uint _fee,
uint _maxDebt,
uint _initialDebt
) external onlyPolicy() {
terms = Terms ({
controlVariable: _controlVariable,
vestingTerm: _vestingTerm,
minimumPrice: _minimumPrice,
maximumDiscount: _maximumDiscount,
maxPayout: _maxPayout,
fee: _fee,
maxDebt: _maxDebt
});
totalDebt = _initialDebt;
lastDecay = block.number;
}
/* ======== POLICY FUNCTIONS ======== */
enum PARAMETER { VESTING, PAYOUT, FEE, DEBT, MIN_PRICE }
/**
* @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 10000 blocks" );
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;
} else if ( _parameter == PARAMETER.MIN_PRICE ) { // 4
terms.minimumPrice = _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() {
adjustment = Adjust({
add: _addition,
rate: _increment,
target: _target,
buffer: _buffer,
lastBlock: block.number
});
}
/**
* @notice set contract for auto stake
* @param _staking address
*/
function setStaking( address _staking ) external onlyPolicy() {
require( _staking != address(0) );
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 >= 10000000, "Bond too small" ); // must be > 0.01 FHM ( 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) FHM
*/
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( FHM ).safeTransfer( DAO, fee );
}
// total debt is increased
totalDebt = totalDebt.add( value );
IERC20( FHM ).approve( staking, payout );
IStaking( staking ).stake( payout, address(this) );
uint stakedGons = IsFHM( sFHM ).gonsForBalance( payout );
// depositor info is stored
_bondInfo[ _depositor ] = Bond({
gonsPayout: _bondInfo[ _depositor ].gonsPayout.add( stakedGons ),
fhmPayout: _bondInfo[ _depositor ].fhmPayout.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)
require ( percentVested >= 10000 , "Wait for end of bond") ;
IStaking( staking ).claim( address(this) );
delete _bondInfo[ _recipient ]; // delete user info
uint _amount = IsFHM( sFHM ).balanceForGons(info.gonsPayout);
emit BondRedeemed( _recipient, _amount, 0 ); // emit bond data
IERC20( sFHM ).transfer( _recipient, _amount ); // pay user everything due
return _amount;
}
/* ======== INTERNAL HELPER FUNCTIONS ======== */
/**
* @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 IFHMCirculatingSupply(fhmCirculatingSupply).OHMCirculatingSupply().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;
}
uint minimalPrice = getMinimalBondPrice();
if (price_ < minimalPrice) {
price_ = minimalPrice;
}
}
/**
* @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;
}
uint minimalPrice = getMinimalBondPrice();
if (price_ < minimalPrice) {
price_ = minimalPrice;
}
}
function getMinimalBondPrice() public view returns (uint) {
uint marketPrice = IFHUDMinter(fhudMinter).getMarketPrice();
uint discount = marketPrice.mul(terms.maximumDiscount).div(10000);
uint price = marketPrice.sub(discount);
if (isLiquidityBond) {
return price.mul(10 ** IERC20( principle ).decimals()).div(IBondCalculator(bondCalculator).markdown(principle));
} else {
return price;
}
}
/**
* @notice converts bond price to DAI value
* @return price_ uint
*/
function bondPriceInUSD() public view returns ( uint price_ ) {
if( isLiquidityBond ) {
price_ = bondPrice().mul( IBondCalculator( bondCalculator ).markdown( principle ) ).div( 100 );
} else {
price_ = bondPrice().mul( 10 ** IERC20( principle ).decimals() ).div( 100 );
}
}
/**
* @notice return bond info with latest sFHM balance calculated from gons
* @param _depositor address
* @return payout uint
* @return vesting uint
* @return lastBlock uint
* @return pricePaid uint
*/
function bondInfo(address _depositor) public view returns ( uint payout,uint vesting,uint lastBlock,uint pricePaid ) {
Bond memory info = _bondInfo[ _depositor ];
payout = IsFHM( sFHM ).balanceForGons( info.gonsPayout );
vesting = info.vesting;
lastBlock = info.lastBlock;
pricePaid = info.pricePaid;
}
/**
* @notice calculate current ratio of debt to FHM supply
* @return debtRatio_ uint
*/
function debtRatio() public view returns ( uint debtRatio_ ) {
uint supply = IFHMCirculatingSupply(fhmCirculatingSupply).OHMCirculatingSupply();
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 ) {
if ( isLiquidityBond ) {
return debtRatio().mul( IBondCalculator( bondCalculator ).markdown( principle ) ).div( 1e9 );
} else {
return debtRatio();
}
}
/**
* @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 FHM 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 = IsFHM( sFHM ).balanceForGons( _bondInfo[ _depositor ].gonsPayout );
if ( percentVested >= 10000 ) {
pendingPayout_ = payout;
} else {
pendingPayout_ = 0;
}
}
/* ======= AUXILLIARY ======= */
/**
* @notice allow anyone to send lost tokens (excluding principle or FHM) to the DAO
* @return bool
*/
function recoverLostToken( address _token ) external returns ( bool ) {
require( _token != FHM);
require( _token != sFHM);
require( _token != principle );
IERC20( _token ).safeTransfer( DAO, IERC20( _token ).balanceOf( address(this) ) );
return true;
}
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_FHM","type":"address"},{"internalType":"address","name":"_sFHM","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"},{"internalType":"address","name":"_fhudMinter","type":"address"},{"internalType":"address","name":"_fhmCirculatingSupply","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":"FHM","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_bondInfo","outputs":[{"internalType":"uint256","name":"gonsPayout","type":"uint256"},{"internalType":"uint256","name":"fhmPayout","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":"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":"_depositor","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":[],"name":"fhmCirculatingSupply","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fhudMinter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMinimalBondPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_controlVariable","type":"uint256"},{"internalType":"uint256","name":"_vestingTerm","type":"uint256"},{"internalType":"uint256","name":"_minimumPrice","type":"uint256"},{"internalType":"uint256","name":"_maximumDiscount","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":"isLiquidityBond","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":[],"name":"sFHM","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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 FantohmBondStakingDepository.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"}],"name":"setStaking","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"staking","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":"maximumDiscount","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"}]Contract Creation Code
6101a06040523480156200001257600080fd5b506040516200315f3803806200315f83398181016040526101008110156200003957600080fd5b50805160208201516040808401516060850151608086015160a087015160c088015160e090980151600080546001600160a01b031916331780825596519899979895979496939592949391926001600160a01b0392909216917fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba908290a36001600160a01b038816620000cb57600080fd5b6001600160601b0319606089901b166080526001600160a01b038716620000f157600080fd5b6001600160601b0319606088901b1660a0526001600160a01b0386166200011757600080fd5b6001600160601b0319606087901b1660c0526001600160a01b0385166200013d57600080fd5b6001600160601b0319606086901b1660e0526001600160a01b0384166200016357600080fd5b6001600160601b0319606085901b16610100526001600160a01b0382166200018a57600080fd5b6001600160601b0319606083901b16610120526001600160a01b038116620001b157600080fd5b6001600160601b0319606091821b8116610140529083901b1661018052506001600160a01b0316151560f81b61016052505050505060805160601c60a05160601c60c05160601c60e05160601c6101005160601c6101205160601c6101405160601c6101605160f81c6101805160601c612e516200030e60003980610f0f528061136e5280611d6c5280611ff2525080610ee652806113405280611d3b528061221a525080611e59528061214d52806122a95250806107d35280610e2f5250806119695280611e355280611f3f5250806112d952806115d752806117db52806118bd5250806106215280610f3e5280610fe4528061139d52806114445280611606528061178252806117ac528061188c5280611d9b5280611efd5250806106555280610bce5280610c895280610d385280611ae55280611ebe52806120b9525080610d5c528061194752806119ca5280611e7f5250612e516000f3fe608060405234801561001057600080fd5b50600436106102325760003560e01c80637927ebf811610130578063c6b2c4cd116100b8578063d7ccfb0b1161007c578063d7ccfb0b146105f7578063e0176de8146105ff578063e392a26214610607578063f5c2ab5b1461060f578063fc7b9c181461061757610232565b8063c6b2c4cd1461050a578063cd1234b31461055b578063cea55f57146105a7578063d5025625146105af578063d7969060146105ef57610232565b8063904b3ece116100ff578063904b3ece146104b057806398fabd3a146104b8578063a83219c8146104c0578063b4abccba146104c8578063c5332b7c1461050257610232565b80637927ebf814610433578063844b5c7c146104505780638dbdbe6d146104585780638ff390991461048a57610232565b806330c90e63116101be5780634cf088d9116101825780634cf088d9146103ed578063507930ec146103f55780635a96ac0a1461041b57806361d027b314610423578063759076e51461042b57610232565b806330c90e631461033a5780633283ad0e1461034257806338b2769b1461038a578063451ee4a11461039257806346f68ee9146103c757610232565b806308be2ad31161020557806308be2ad3146102a55780631a3d0068146102ad5780631e321a0f146102de5780631feed31f146103045780632a280f5b1461033257610232565b8063016a42841461023757806301b88ee81461025b5780630505c8c914610293578063089208d81461029b575b600080fd5b61023f61061f565b604080516001600160a01b039092168252519081900360200190f35b6102816004803603602081101561027157600080fd5b50356001600160a01b0316610643565b60408051918252519081900360200190f35b61023f61072a565b6102a361073a565b005b61023f6107d1565b6102a3600480360360808110156102c357600080fd5b508035151590602081013590604081013590606001356107f5565b6102a3600480360360408110156102f457600080fd5b5060ff813516906020013561088d565b6102816004803603604081101561031a57600080fd5b506001600160a01b0381351690602001351515610a5f565b61023f610d36565b61023f610d5a565b6102a3600480360361010081101561035957600080fd5b5080359060208101359060408101359060608101359060808101359060a08101359060c08101359060e00135610d7e565b610281610e2a565b61039a611078565b60408051951515865260208601949094528484019290925260608401526080830152519081900360a00190f35b6102a3600480360360208110156103dd57600080fd5b50356001600160a01b0316611090565b61023f61117d565b6102816004803603602081101561040b57600080fd5b50356001600160a01b031661118c565b6102a361122d565b61023f6112d7565b6102816112fb565b6102816004803603602081101561044957600080fd5b5035611316565b61028161133c565b6102816004803603606081101561046e57600080fd5b50803590602081013590604001356001600160a01b03166114d5565b6102a3600480360360208110156104a057600080fd5b50356001600160a01b0316611cb5565b610281611d37565b61023f611e33565b61023f611e57565b6104ee600480360360208110156104de57600080fd5b50356001600160a01b0316611e7b565b604080519115158252519081900360200190f35b61023f611ff0565b6105306004803603602081101561052057600080fd5b50356001600160a01b0316612014565b6040805195865260208601949094528484019290925260608401526080830152519081900360a00190f35b6105816004803603602081101561057157600080fd5b50356001600160a01b0316612043565b604080519485526020850193909352838301919091526060830152519081900360800190f35b610281612148565b6105b7612200565b604080519788526020880196909652868601949094526060860192909252608085015260a084015260c0830152519081900360e00190f35b6104ee612218565b61028161223c565b610281612295565b610281612332565b610281612375565b61028161237b565b7f000000000000000000000000000000000000000000000000000000000000000081565b60008061064f8361118c565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316637965d56d600f6000876001600160a01b03166001600160a01b03168152602001908152602001600020600001546040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156106df57600080fd5b505afa1580156106f3573d6000803e3d6000fd5b505050506040513d602081101561070957600080fd5b50519050612710821061071e57809250610723565b600092505b5050919050565b6000546001600160a01b03165b90565b6000546001600160a01b03163314610787576040805162461bcd60e51b81526020600482018190526024820152600080516020612daf833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba908390a3600080546001600160a01b0319169055565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000546001600160a01b03163314610842576040805162461bcd60e51b81526020600482018190526024820152600080516020612daf833981519152604482015290519081900360640190fd5b6040805160a0810182529415158086526020860185905290850183905260608501829052436080909501859052600a805460ff19169091179055600b92909255600c55600d55600e55565b6000546001600160a01b031633146108da576040805162461bcd60e51b81526020600482018190526024820152600080516020612daf833981519152604482015290519081900360640190fd5b60008260048111156108e857fe5b14156109395761271081101561092f5760405162461bcd60e51b8152600401808060200182810382526028815260200180612d666028913960400191505060405180910390fd5b6004819055610a5b565b600182600481111561094757fe5b14156109ae576103e88111156109a4576040805162461bcd60e51b815260206004820181905260248201527f5061796f75742063616e6e6f742062652061626f766520312070657263656e74604482015290519081900360640190fd5b6007819055610a5b565b60028260048111156109bc57fe5b1415610a2357612710811115610a19576040805162461bcd60e51b815260206004820152601c60248201527f44414f206665652063616e6e6f7420657863656564207061796f757400000000604482015290519081900360640190fd5b6008819055610a5b565b6003826004811115610a3157fe5b1415610a41576009819055610a5b565b6004826004811115610a4f57fe5b1415610a5b5760058190555b5050565b6000610a69612cb6565b506001600160a01b0383166000908152600f60209081526040808320815160a081018352815481526001820154938101939093526002810154918301919091526003810154606083015260040154608082015290610ac68561118c565b9050612710811015610b16576040805162461bcd60e51b815260206004820152601460248201527315d85a5d08199bdc88195b99081bd988189bdb9960621b604482015290519081900360640190fd5b60025460408051630f41a04d60e11b815230600482015290516001600160a01b0390921691631e83409a9160248082019260009290919082900301818387803b158015610b6257600080fd5b505af1158015610b76573d6000803e3d6000fd5b5050506001600160a01b038087166000908152600f60209081526040808320838155600181018490556002810184905560038101849055600490810184905587518251637965d56d60e01b81529182015290519294507f000000000000000000000000000000000000000000000000000000000000000090931692637965d56d9260248083019392829003018186803b158015610c1257600080fd5b505afa158015610c26573d6000803e3d6000fd5b505050506040513d6020811015610c3c57600080fd5b5051604080518281526000602082015281519293506001600160a01b038916927f51c99f515c87b0d95ba97f616edd182e8f161c4932eac17c6fefe9dab58b77b1929181900390910190a27f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb87836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015610cfe57600080fd5b505af1158015610d12573d6000803e3d6000fd5b505050506040513d6020811015610d2857600080fd5b509093505050505b92915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000546001600160a01b03163314610dcb576040805162461bcd60e51b81526020600482018190526024820152600080516020612daf833981519152604482015290519081900360640190fd5b6040805160e08101825289815260208101899052908101879052606081018690526080810185905260a0810184905260c00182905260039790975560049590955560059390935560069190915560075560085560095560105543601155565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663660e16c36040518163ffffffff1660e01b815260040160206040518083038186803b158015610e8657600080fd5b505afa158015610e9a573d6000803e3d6000fd5b505050506040513d6020811015610eb057600080fd5b5051600654909150600090610ed49061271090610ece908590612381565b906123e1565b90506000610ee28383612423565b90507f00000000000000000000000000000000000000000000000000000000000000001561106e576110647f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166332da80a37f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610f9a57600080fd5b505afa158015610fae573d6000803e3d6000fd5b505050506040513d6020811015610fc457600080fd5b50516040805163313ce56760e01b81529051610ece916001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163313ce56791600480820192602092909190829003018186803b15801561102b57600080fd5b505afa15801561103f573d6000803e3d6000fd5b505050506040513d602081101561105557600080fd5b5051849060ff16600a0a612381565b9350505050610737565b9250610737915050565b600a54600b54600c54600d54600e5460ff9094169385565b6000546001600160a01b031633146110dd576040805162461bcd60e51b81526020600482018190526024820152600080516020612daf833981519152604482015290519081900360640190fd5b6001600160a01b0381166111225760405162461bcd60e51b8152600401808060200182810382526026815260200180612cf86026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba91a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b031681565b6000611196612cb6565b506001600160a01b0382166000908152600f60209081526040808320815160a0810183528154815260018201549381019390935260028101549183019190915260038101546060830181905260049091015460808301529091906111fb904390612423565b604083015190915080156112205761121981610ece84612710612381565b9350611225565b600093505b505050919050565b6001546001600160a01b031633146112765760405162461bcd60e51b8152600401808060200182810382526022815260200180612d1e6022913960400191505060405180910390fd5b600154600080546040516001600160a01b0393841693909116917faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d91a3600154600080546001600160a01b0319166001600160a01b03909216919091179055565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000611311611308612332565b60105490612423565b905090565b6000610d30662386f26fc10000610ece6113378561133261223c565b612465565b6125dc565b60007f00000000000000000000000000000000000000000000000000000000000000001561143a576114336064610ece7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166332da80a37f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156113f957600080fd5b505afa15801561140d573d6000803e3d6000fd5b505050506040513d602081101561142357600080fd5b505161142d61223c565b90612381565b9050610737565b6113116064610ece7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561149b57600080fd5b505afa1580156114af573d6000803e3d6000fd5b505050506040513d60208110156114c557600080fd5b505160ff16600a0a61142d61223c565b60006001600160a01b038216611524576040805162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015290519081900360640190fd5b61152c6125f4565b600954601054111561157c576040805162461bcd60e51b815260206004820152601460248201527313585e0818d85c1858da5d1e481c995858da195960621b604482015290519081900360640190fd5b600061158661133c565b90506000611592612608565b9050808510156115d35760405162461bcd60e51b8152600401808060200182810382526023815260200180612dcf6023913960400191505060405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631eec5a9a7f0000000000000000000000000000000000000000000000000000000000000000896040518363ffffffff1660e01b815260040180836001600160a01b031681526020018281526020019250505060206040518083038186803b15801561166a57600080fd5b505afa15801561167e573d6000803e3d6000fd5b505050506040513d602081101561169457600080fd5b5051905060006116a382611316565b9050629896808110156116ee576040805162461bcd60e51b815260206004820152600e60248201526d109bdb99081d1bdbc81cdb585b1b60921b604482015290519081900360640190fd5b6116f6612295565b81111561173b576040805162461bcd60e51b815260206004820152600e60248201526d426f6e6420746f6f206c6172676560901b604482015290519081900360640190fd5b600061175b612710610ece6003600501548561238190919063ffffffff16565b905060006117738261176d8686612423565b90612423565b90506117aa6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308d612651565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663095ea7b37f00000000000000000000000000000000000000000000000000000000000000008c6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561184157600080fd5b505af1158015611855573d6000803e3d6000fd5b505050506040513d602081101561186b57600080fd5b50506040805163bc157ac160e01b8152600481018c90526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248301526044820184905291517f00000000000000000000000000000000000000000000000000000000000000009092169163bc157ac1916064808201926020929091908290030181600087803b15801561190857600080fd5b505af115801561191c573d6000803e3d6000fd5b505050506040513d602081101561193257600080fd5b5050811561198e5761198e6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000846126b1565b60105461199b9085612708565b6010556002546040805163095ea7b360e01b81526001600160a01b0392831660048201526024810186905290517f00000000000000000000000000000000000000000000000000000000000000009092169163095ea7b3916044808201926020929091908290030181600087803b158015611a1557600080fd5b505af1158015611a29573d6000803e3d6000fd5b505050506040513d6020811015611a3f57600080fd5b505060025460408051637acb775760e01b81526004810186905230602482015290516001600160a01b0390921691637acb7757916044808201926020929091908290030181600087803b158015611a9557600080fd5b505af1158015611aa9573d6000803e3d6000fd5b505050506040513d6020811015611abf57600080fd5b5050604080516306f4e59d60e21b81526004810185905290516000916001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691631bd3967491602480820192602092909190829003018186803b158015611b2c57600080fd5b505afa158015611b40573d6000803e3d6000fd5b505050506040513d6020811015611b5657600080fd5b50516040805160a0810182526001600160a01b038c166000908152600f6020529190912054919250908190611b8b9084612708565b81526001600160a01b038b166000908152600f6020908152604090912060010154910190611bb99087612708565b81526004805460208084019190915243604080850182905260609485018d90526001600160a01b038f166000908152600f84528190208651815592860151600184015585015160028301559284015160038201556080909301519281019290925590548891611c2791612708565b604080518e8152905187917f1fec6dc81f140574bf43f6b1e420ae1dd47928b9d57db8cbd7b8611063b85ae5919081900360200190a4611c65612148565b611c6d612608565b611c7561133c565b6040517f375b221f40939bfd8f49723a17cf7bc6d576ebf72efe2cc3e991826f5b3f390a90600090a4611ca6612762565b50919998505050505050505050565b6000546001600160a01b03163314611d02576040805162461bcd60e51b81526020600482018190526024820152600080516020612daf833981519152604482015290519081900360640190fd5b6001600160a01b038116611d1557600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60007f000000000000000000000000000000000000000000000000000000000000000015611e2b57611433633b9aca00610ece7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166332da80a37f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611df757600080fd5b505afa158015611e0b573d6000803e3d6000fd5b505050506040513d6020811015611e2157600080fd5b505161142d612148565b611433612148565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611ebc57600080fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611efb57600080fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611f3a57600080fd5b611fe87f0000000000000000000000000000000000000000000000000000000000000000836001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611fab57600080fd5b505afa158015611fbf573d6000803e3d6000fd5b505050506040513d6020811015611fd557600080fd5b50516001600160a01b03851691906126b1565b506001919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600f60205260009081526040902080546001820154600283015460038401546004909401549293919290919085565b600080600080612051612cb6565b506001600160a01b038086166000908152600f6020908152604091829020825160a08101845281548082526001830154828501526002830154828601526003830154606083015260049283015460808301528451637965d56d60e01b815292830152925192937f00000000000000000000000000000000000000000000000000000000000000001692637965d56d92602480840193919291829003018186803b1580156120fd57600080fd5b505afa158015612111573d6000803e3d6000fd5b505050506040513d602081101561212757600080fd5b50516040820151606083015160809093015191989097509195509350915050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1455626040518163ffffffff1660e01b815260040160206040518083038186803b1580156121a457600080fd5b505afa1580156121b8573d6000803e3d6000fd5b505050506040513d60208110156121ce57600080fd5b505190506121fa670de0b6b3a7640000610ece6113376121f4633b9aca0061142d6112fb565b85612465565b91505090565b60035460045460055460065460075460085460095487565b7f000000000000000000000000000000000000000000000000000000000000000081565b600061226762989680610ece633b9aca00612261612258612148565b60035490612381565b90612708565b60055490915081101561227957506005545b6000612283610e2a565b905080821015612291578091505b5090565b6000611311620186a0610ece6003600401547f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1455626040518163ffffffff1660e01b815260040160206040518083038186803b15801561230057600080fd5b505afa158015612314573d6000803e3d6000fd5b505050506040513d602081101561232a57600080fd5b505190612381565b60008061234a6011544361242390919063ffffffff16565b60045460105491925061236191610ece9084612381565b915060105482111561229157505060105490565b60115481565b60105481565b60008261239057506000610d30565b8282028284828161239d57fe5b04146123da5760405162461bcd60e51b8152600401808060200182810382526021815260200180612d8e6021913960400191505060405180910390fd5b9392505050565b60006123da83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612842565b60006123da83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506128e4565b61246d612ce5565b600082116124ac5760405162461bcd60e51b8152600401808060200182810382526026815260200180612d406026913960400191505060405180910390fd5b826124c65750604080516020810190915260008152610d30565b71ffffffffffffffffffffffffffffffffffff831161256d57600082607085901b816124ee57fe5b0490506001600160e01b0381111561254d576040805162461bcd60e51b815260206004820152601e60248201527f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f770000604482015290519081900360640190fd5b6040518060200160405280826001600160e01b0316815250915050610d30565b600061257e84600160701b8561293e565b90506001600160e01b0381111561254d576040805162461bcd60e51b815260206004820152601e60248201527f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f770000604482015290519081900360640190fd5b516612725dd1d243ab6001600160e01b039091160490565b6125ff611308612332565b60105543601155565b600061262462989680610ece633b9aca00612261612258612148565b60055490915081101561263a5750600554612279565b600554156122795760006005556000612283610e2a565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526126ab9085906129de565b50505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526127039084906129de565b505050565b6000828201838110156123da576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600d54600e546000916127759190612708565b600b54909150158015906127895750804310155b1561283f57600354600a5460ff16156127c357600b546003546127ab91612708565b6003819055600c54116127be576000600b555b6127e5565b600b546003546127d291612423565b6003819055600c54106127e5576000600b555b43600e55600354600b54600a546040805185815260208101949094528381019290925260ff1615156060830152517fb923e581a0f83128e9e1d8297aa52b18d6744310476e0b54509c054cd7a93b2a9181900360800190a1505b50565b600081836128ce5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561289357818101518382015260200161287b565b50505050905090810190601f1680156128c05780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816128da57fe5b0495945050505050565b600081848411156129365760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561289357818101518382015260200161287b565b505050900390565b600080600061294d8686612a8f565b915091506000848061295b57fe5b86880990508281111561296f576001820391505b80830392508482106129c8576040805162461bcd60e51b815260206004820152601a60248201527f46756c6c4d6174683a3a6d756c4469763a206f766572666c6f77000000000000604482015290519081900360640190fd5b6129d3838387612abc565b979650505050505050565b6060612a33826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612b2c9092919063ffffffff16565b80519091501561270357808060200190516020811015612a5257600080fd5b50516127035760405162461bcd60e51b815260040180806020018281038252602a815260200180612df2602a913960400191505060405180910390fd5b6000808060001984860990508385029250828103915082811015612ab4576001820391505b509250929050565b60008181038216808381612acc57fe5b049250808581612ad857fe5b049450808160000381612ae757fe5b60028581038087028203028087028203028087028203028087028203028087028203028087028203029586029003909402930460010193909302939093010292915050565b6060612b3b8484600085612b43565b949350505050565b6060612b4e85612cb0565b612b9f576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b60208310612bde5780518252601f199092019160209182019101612bbf565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114612c40576040519150601f19603f3d011682016040523d82523d6000602084013e612c45565b606091505b50915091508115612c59579150612b3b9050565b805115612c695780518082602001fd5b60405162461bcd60e51b815260206004820181815286516024840152865187939192839260440191908501908083836000831561289357818101518382015260200161287b565b3b151590565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b6040805160208101909152600081529056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6c4669786564506f696e743a3a6672616374696f6e3a206469766973696f6e206279207a65726f56657374696e67206d757374206265206c6f6e676572207468616e20313030303020626c6f636b73536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572536c697070616765206c696d69743a206d6f7265207468616e206d61782070726963655361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220dfeb4d9044705c8c89935c4c73c1a1954073bcb35ba39600675af9a6e796b78164736f6c63430007050033000000000000000000000000fa1fbb8ef55a4855e5688c0ee13ac3f2024862860000000000000000000000001888bb30f9edd63b265942f3e3d061f186f38079000000000000000000000000e3f5a90f9cb311505cd691a46596599aa1a0ad7d0000000000000000000000005e983ff70de345de15dbdcf0529640f14446cdfa000000000000000000000000e3cd5475f18a97d3563307b4e1a64674702379270000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b180c7bbd35bae57d5eb4b4fc0516c4d50b5bf830000000000000000000000009dc084fd82860cdb4ed2b2bf59f1076f47b03bd6
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102325760003560e01c80637927ebf811610130578063c6b2c4cd116100b8578063d7ccfb0b1161007c578063d7ccfb0b146105f7578063e0176de8146105ff578063e392a26214610607578063f5c2ab5b1461060f578063fc7b9c181461061757610232565b8063c6b2c4cd1461050a578063cd1234b31461055b578063cea55f57146105a7578063d5025625146105af578063d7969060146105ef57610232565b8063904b3ece116100ff578063904b3ece146104b057806398fabd3a146104b8578063a83219c8146104c0578063b4abccba146104c8578063c5332b7c1461050257610232565b80637927ebf814610433578063844b5c7c146104505780638dbdbe6d146104585780638ff390991461048a57610232565b806330c90e63116101be5780634cf088d9116101825780634cf088d9146103ed578063507930ec146103f55780635a96ac0a1461041b57806361d027b314610423578063759076e51461042b57610232565b806330c90e631461033a5780633283ad0e1461034257806338b2769b1461038a578063451ee4a11461039257806346f68ee9146103c757610232565b806308be2ad31161020557806308be2ad3146102a55780631a3d0068146102ad5780631e321a0f146102de5780631feed31f146103045780632a280f5b1461033257610232565b8063016a42841461023757806301b88ee81461025b5780630505c8c914610293578063089208d81461029b575b600080fd5b61023f61061f565b604080516001600160a01b039092168252519081900360200190f35b6102816004803603602081101561027157600080fd5b50356001600160a01b0316610643565b60408051918252519081900360200190f35b61023f61072a565b6102a361073a565b005b61023f6107d1565b6102a3600480360360808110156102c357600080fd5b508035151590602081013590604081013590606001356107f5565b6102a3600480360360408110156102f457600080fd5b5060ff813516906020013561088d565b6102816004803603604081101561031a57600080fd5b506001600160a01b0381351690602001351515610a5f565b61023f610d36565b61023f610d5a565b6102a3600480360361010081101561035957600080fd5b5080359060208101359060408101359060608101359060808101359060a08101359060c08101359060e00135610d7e565b610281610e2a565b61039a611078565b60408051951515865260208601949094528484019290925260608401526080830152519081900360a00190f35b6102a3600480360360208110156103dd57600080fd5b50356001600160a01b0316611090565b61023f61117d565b6102816004803603602081101561040b57600080fd5b50356001600160a01b031661118c565b6102a361122d565b61023f6112d7565b6102816112fb565b6102816004803603602081101561044957600080fd5b5035611316565b61028161133c565b6102816004803603606081101561046e57600080fd5b50803590602081013590604001356001600160a01b03166114d5565b6102a3600480360360208110156104a057600080fd5b50356001600160a01b0316611cb5565b610281611d37565b61023f611e33565b61023f611e57565b6104ee600480360360208110156104de57600080fd5b50356001600160a01b0316611e7b565b604080519115158252519081900360200190f35b61023f611ff0565b6105306004803603602081101561052057600080fd5b50356001600160a01b0316612014565b6040805195865260208601949094528484019290925260608401526080830152519081900360a00190f35b6105816004803603602081101561057157600080fd5b50356001600160a01b0316612043565b604080519485526020850193909352838301919091526060830152519081900360800190f35b610281612148565b6105b7612200565b604080519788526020880196909652868601949094526060860192909252608085015260a084015260c0830152519081900360e00190f35b6104ee612218565b61028161223c565b610281612295565b610281612332565b610281612375565b61028161237b565b7f000000000000000000000000e3f5a90f9cb311505cd691a46596599aa1a0ad7d81565b60008061064f8361118c565b905060007f0000000000000000000000001888bb30f9edd63b265942f3e3d061f186f380796001600160a01b0316637965d56d600f6000876001600160a01b03166001600160a01b03168152602001908152602001600020600001546040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156106df57600080fd5b505afa1580156106f3573d6000803e3d6000fd5b505050506040513d602081101561070957600080fd5b50519050612710821061071e57809250610723565b600092505b5050919050565b6000546001600160a01b03165b90565b6000546001600160a01b03163314610787576040805162461bcd60e51b81526020600482018190526024820152600080516020612daf833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba908390a3600080546001600160a01b0319169055565b7f000000000000000000000000b180c7bbd35bae57d5eb4b4fc0516c4d50b5bf8381565b6000546001600160a01b03163314610842576040805162461bcd60e51b81526020600482018190526024820152600080516020612daf833981519152604482015290519081900360640190fd5b6040805160a0810182529415158086526020860185905290850183905260608501829052436080909501859052600a805460ff19169091179055600b92909255600c55600d55600e55565b6000546001600160a01b031633146108da576040805162461bcd60e51b81526020600482018190526024820152600080516020612daf833981519152604482015290519081900360640190fd5b60008260048111156108e857fe5b14156109395761271081101561092f5760405162461bcd60e51b8152600401808060200182810382526028815260200180612d666028913960400191505060405180910390fd5b6004819055610a5b565b600182600481111561094757fe5b14156109ae576103e88111156109a4576040805162461bcd60e51b815260206004820181905260248201527f5061796f75742063616e6e6f742062652061626f766520312070657263656e74604482015290519081900360640190fd5b6007819055610a5b565b60028260048111156109bc57fe5b1415610a2357612710811115610a19576040805162461bcd60e51b815260206004820152601c60248201527f44414f206665652063616e6e6f7420657863656564207061796f757400000000604482015290519081900360640190fd5b6008819055610a5b565b6003826004811115610a3157fe5b1415610a41576009819055610a5b565b6004826004811115610a4f57fe5b1415610a5b5760058190555b5050565b6000610a69612cb6565b506001600160a01b0383166000908152600f60209081526040808320815160a081018352815481526001820154938101939093526002810154918301919091526003810154606083015260040154608082015290610ac68561118c565b9050612710811015610b16576040805162461bcd60e51b815260206004820152601460248201527315d85a5d08199bdc88195b99081bd988189bdb9960621b604482015290519081900360640190fd5b60025460408051630f41a04d60e11b815230600482015290516001600160a01b0390921691631e83409a9160248082019260009290919082900301818387803b158015610b6257600080fd5b505af1158015610b76573d6000803e3d6000fd5b5050506001600160a01b038087166000908152600f60209081526040808320838155600181018490556002810184905560038101849055600490810184905587518251637965d56d60e01b81529182015290519294507f0000000000000000000000001888bb30f9edd63b265942f3e3d061f186f3807990931692637965d56d9260248083019392829003018186803b158015610c1257600080fd5b505afa158015610c26573d6000803e3d6000fd5b505050506040513d6020811015610c3c57600080fd5b5051604080518281526000602082015281519293506001600160a01b038916927f51c99f515c87b0d95ba97f616edd182e8f161c4932eac17c6fefe9dab58b77b1929181900390910190a27f0000000000000000000000001888bb30f9edd63b265942f3e3d061f186f380796001600160a01b031663a9059cbb87836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015610cfe57600080fd5b505af1158015610d12573d6000803e3d6000fd5b505050506040513d6020811015610d2857600080fd5b509093505050505b92915050565b7f0000000000000000000000001888bb30f9edd63b265942f3e3d061f186f3807981565b7f000000000000000000000000fa1fbb8ef55a4855e5688c0ee13ac3f20248628681565b6000546001600160a01b03163314610dcb576040805162461bcd60e51b81526020600482018190526024820152600080516020612daf833981519152604482015290519081900360640190fd5b6040805160e08101825289815260208101899052908101879052606081018690526080810185905260a0810184905260c00182905260039790975560049590955560059390935560069190915560075560085560095560105543601155565b6000807f000000000000000000000000b180c7bbd35bae57d5eb4b4fc0516c4d50b5bf836001600160a01b031663660e16c36040518163ffffffff1660e01b815260040160206040518083038186803b158015610e8657600080fd5b505afa158015610e9a573d6000803e3d6000fd5b505050506040513d6020811015610eb057600080fd5b5051600654909150600090610ed49061271090610ece908590612381565b906123e1565b90506000610ee28383612423565b90507f00000000000000000000000000000000000000000000000000000000000000001561106e576110647f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166332da80a37f000000000000000000000000e3f5a90f9cb311505cd691a46596599aa1a0ad7d6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610f9a57600080fd5b505afa158015610fae573d6000803e3d6000fd5b505050506040513d6020811015610fc457600080fd5b50516040805163313ce56760e01b81529051610ece916001600160a01b037f000000000000000000000000e3f5a90f9cb311505cd691a46596599aa1a0ad7d169163313ce56791600480820192602092909190829003018186803b15801561102b57600080fd5b505afa15801561103f573d6000803e3d6000fd5b505050506040513d602081101561105557600080fd5b5051849060ff16600a0a612381565b9350505050610737565b9250610737915050565b600a54600b54600c54600d54600e5460ff9094169385565b6000546001600160a01b031633146110dd576040805162461bcd60e51b81526020600482018190526024820152600080516020612daf833981519152604482015290519081900360640190fd5b6001600160a01b0381166111225760405162461bcd60e51b8152600401808060200182810382526026815260200180612cf86026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba91a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b031681565b6000611196612cb6565b506001600160a01b0382166000908152600f60209081526040808320815160a0810183528154815260018201549381019390935260028101549183019190915260038101546060830181905260049091015460808301529091906111fb904390612423565b604083015190915080156112205761121981610ece84612710612381565b9350611225565b600093505b505050919050565b6001546001600160a01b031633146112765760405162461bcd60e51b8152600401808060200182810382526022815260200180612d1e6022913960400191505060405180910390fd5b600154600080546040516001600160a01b0393841693909116917faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d91a3600154600080546001600160a01b0319166001600160a01b03909216919091179055565b7f0000000000000000000000005e983ff70de345de15dbdcf0529640f14446cdfa81565b6000611311611308612332565b60105490612423565b905090565b6000610d30662386f26fc10000610ece6113378561133261223c565b612465565b6125dc565b60007f00000000000000000000000000000000000000000000000000000000000000001561143a576114336064610ece7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166332da80a37f000000000000000000000000e3f5a90f9cb311505cd691a46596599aa1a0ad7d6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156113f957600080fd5b505afa15801561140d573d6000803e3d6000fd5b505050506040513d602081101561142357600080fd5b505161142d61223c565b90612381565b9050610737565b6113116064610ece7f000000000000000000000000e3f5a90f9cb311505cd691a46596599aa1a0ad7d6001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561149b57600080fd5b505afa1580156114af573d6000803e3d6000fd5b505050506040513d60208110156114c557600080fd5b505160ff16600a0a61142d61223c565b60006001600160a01b038216611524576040805162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015290519081900360640190fd5b61152c6125f4565b600954601054111561157c576040805162461bcd60e51b815260206004820152601460248201527313585e0818d85c1858da5d1e481c995858da195960621b604482015290519081900360640190fd5b600061158661133c565b90506000611592612608565b9050808510156115d35760405162461bcd60e51b8152600401808060200182810382526023815260200180612dcf6023913960400191505060405180910390fd5b60007f0000000000000000000000005e983ff70de345de15dbdcf0529640f14446cdfa6001600160a01b0316631eec5a9a7f000000000000000000000000e3f5a90f9cb311505cd691a46596599aa1a0ad7d896040518363ffffffff1660e01b815260040180836001600160a01b031681526020018281526020019250505060206040518083038186803b15801561166a57600080fd5b505afa15801561167e573d6000803e3d6000fd5b505050506040513d602081101561169457600080fd5b5051905060006116a382611316565b9050629896808110156116ee576040805162461bcd60e51b815260206004820152600e60248201526d109bdb99081d1bdbc81cdb585b1b60921b604482015290519081900360640190fd5b6116f6612295565b81111561173b576040805162461bcd60e51b815260206004820152600e60248201526d426f6e6420746f6f206c6172676560901b604482015290519081900360640190fd5b600061175b612710610ece6003600501548561238190919063ffffffff16565b905060006117738261176d8686612423565b90612423565b90506117aa6001600160a01b037f000000000000000000000000e3f5a90f9cb311505cd691a46596599aa1a0ad7d1633308d612651565b7f000000000000000000000000e3f5a90f9cb311505cd691a46596599aa1a0ad7d6001600160a01b031663095ea7b37f0000000000000000000000005e983ff70de345de15dbdcf0529640f14446cdfa8c6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561184157600080fd5b505af1158015611855573d6000803e3d6000fd5b505050506040513d602081101561186b57600080fd5b50506040805163bc157ac160e01b8152600481018c90526001600160a01b037f000000000000000000000000e3f5a90f9cb311505cd691a46596599aa1a0ad7d811660248301526044820184905291517f0000000000000000000000005e983ff70de345de15dbdcf0529640f14446cdfa9092169163bc157ac1916064808201926020929091908290030181600087803b15801561190857600080fd5b505af115801561191c573d6000803e3d6000fd5b505050506040513d602081101561193257600080fd5b5050811561198e5761198e6001600160a01b037f000000000000000000000000fa1fbb8ef55a4855e5688c0ee13ac3f202486286167f000000000000000000000000e3cd5475f18a97d3563307b4e1a6467470237927846126b1565b60105461199b9085612708565b6010556002546040805163095ea7b360e01b81526001600160a01b0392831660048201526024810186905290517f000000000000000000000000fa1fbb8ef55a4855e5688c0ee13ac3f2024862869092169163095ea7b3916044808201926020929091908290030181600087803b158015611a1557600080fd5b505af1158015611a29573d6000803e3d6000fd5b505050506040513d6020811015611a3f57600080fd5b505060025460408051637acb775760e01b81526004810186905230602482015290516001600160a01b0390921691637acb7757916044808201926020929091908290030181600087803b158015611a9557600080fd5b505af1158015611aa9573d6000803e3d6000fd5b505050506040513d6020811015611abf57600080fd5b5050604080516306f4e59d60e21b81526004810185905290516000916001600160a01b037f0000000000000000000000001888bb30f9edd63b265942f3e3d061f186f380791691631bd3967491602480820192602092909190829003018186803b158015611b2c57600080fd5b505afa158015611b40573d6000803e3d6000fd5b505050506040513d6020811015611b5657600080fd5b50516040805160a0810182526001600160a01b038c166000908152600f6020529190912054919250908190611b8b9084612708565b81526001600160a01b038b166000908152600f6020908152604090912060010154910190611bb99087612708565b81526004805460208084019190915243604080850182905260609485018d90526001600160a01b038f166000908152600f84528190208651815592860151600184015585015160028301559284015160038201556080909301519281019290925590548891611c2791612708565b604080518e8152905187917f1fec6dc81f140574bf43f6b1e420ae1dd47928b9d57db8cbd7b8611063b85ae5919081900360200190a4611c65612148565b611c6d612608565b611c7561133c565b6040517f375b221f40939bfd8f49723a17cf7bc6d576ebf72efe2cc3e991826f5b3f390a90600090a4611ca6612762565b50919998505050505050505050565b6000546001600160a01b03163314611d02576040805162461bcd60e51b81526020600482018190526024820152600080516020612daf833981519152604482015290519081900360640190fd5b6001600160a01b038116611d1557600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60007f000000000000000000000000000000000000000000000000000000000000000015611e2b57611433633b9aca00610ece7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166332da80a37f000000000000000000000000e3f5a90f9cb311505cd691a46596599aa1a0ad7d6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611df757600080fd5b505afa158015611e0b573d6000803e3d6000fd5b505050506040513d6020811015611e2157600080fd5b505161142d612148565b611433612148565b7f000000000000000000000000e3cd5475f18a97d3563307b4e1a646747023792781565b7f0000000000000000000000009dc084fd82860cdb4ed2b2bf59f1076f47b03bd681565b60007f000000000000000000000000fa1fbb8ef55a4855e5688c0ee13ac3f2024862866001600160a01b0316826001600160a01b03161415611ebc57600080fd5b7f0000000000000000000000001888bb30f9edd63b265942f3e3d061f186f380796001600160a01b0316826001600160a01b03161415611efb57600080fd5b7f000000000000000000000000e3f5a90f9cb311505cd691a46596599aa1a0ad7d6001600160a01b0316826001600160a01b03161415611f3a57600080fd5b611fe87f000000000000000000000000e3cd5475f18a97d3563307b4e1a6467470237927836001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611fab57600080fd5b505afa158015611fbf573d6000803e3d6000fd5b505050506040513d6020811015611fd557600080fd5b50516001600160a01b03851691906126b1565b506001919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600f60205260009081526040902080546001820154600283015460038401546004909401549293919290919085565b600080600080612051612cb6565b506001600160a01b038086166000908152600f6020908152604091829020825160a08101845281548082526001830154828501526002830154828601526003830154606083015260049283015460808301528451637965d56d60e01b815292830152925192937f0000000000000000000000001888bb30f9edd63b265942f3e3d061f186f380791692637965d56d92602480840193919291829003018186803b1580156120fd57600080fd5b505afa158015612111573d6000803e3d6000fd5b505050506040513d602081101561212757600080fd5b50516040820151606083015160809093015191989097509195509350915050565b6000807f0000000000000000000000009dc084fd82860cdb4ed2b2bf59f1076f47b03bd66001600160a01b0316632e1455626040518163ffffffff1660e01b815260040160206040518083038186803b1580156121a457600080fd5b505afa1580156121b8573d6000803e3d6000fd5b505050506040513d60208110156121ce57600080fd5b505190506121fa670de0b6b3a7640000610ece6113376121f4633b9aca0061142d6112fb565b85612465565b91505090565b60035460045460055460065460075460085460095487565b7f000000000000000000000000000000000000000000000000000000000000000081565b600061226762989680610ece633b9aca00612261612258612148565b60035490612381565b90612708565b60055490915081101561227957506005545b6000612283610e2a565b905080821015612291578091505b5090565b6000611311620186a0610ece6003600401547f0000000000000000000000009dc084fd82860cdb4ed2b2bf59f1076f47b03bd66001600160a01b0316632e1455626040518163ffffffff1660e01b815260040160206040518083038186803b15801561230057600080fd5b505afa158015612314573d6000803e3d6000fd5b505050506040513d602081101561232a57600080fd5b505190612381565b60008061234a6011544361242390919063ffffffff16565b60045460105491925061236191610ece9084612381565b915060105482111561229157505060105490565b60115481565b60105481565b60008261239057506000610d30565b8282028284828161239d57fe5b04146123da5760405162461bcd60e51b8152600401808060200182810382526021815260200180612d8e6021913960400191505060405180910390fd5b9392505050565b60006123da83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612842565b60006123da83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506128e4565b61246d612ce5565b600082116124ac5760405162461bcd60e51b8152600401808060200182810382526026815260200180612d406026913960400191505060405180910390fd5b826124c65750604080516020810190915260008152610d30565b71ffffffffffffffffffffffffffffffffffff831161256d57600082607085901b816124ee57fe5b0490506001600160e01b0381111561254d576040805162461bcd60e51b815260206004820152601e60248201527f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f770000604482015290519081900360640190fd5b6040518060200160405280826001600160e01b0316815250915050610d30565b600061257e84600160701b8561293e565b90506001600160e01b0381111561254d576040805162461bcd60e51b815260206004820152601e60248201527f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f770000604482015290519081900360640190fd5b516612725dd1d243ab6001600160e01b039091160490565b6125ff611308612332565b60105543601155565b600061262462989680610ece633b9aca00612261612258612148565b60055490915081101561263a5750600554612279565b600554156122795760006005556000612283610e2a565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526126ab9085906129de565b50505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526127039084906129de565b505050565b6000828201838110156123da576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600d54600e546000916127759190612708565b600b54909150158015906127895750804310155b1561283f57600354600a5460ff16156127c357600b546003546127ab91612708565b6003819055600c54116127be576000600b555b6127e5565b600b546003546127d291612423565b6003819055600c54106127e5576000600b555b43600e55600354600b54600a546040805185815260208101949094528381019290925260ff1615156060830152517fb923e581a0f83128e9e1d8297aa52b18d6744310476e0b54509c054cd7a93b2a9181900360800190a1505b50565b600081836128ce5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561289357818101518382015260200161287b565b50505050905090810190601f1680156128c05780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816128da57fe5b0495945050505050565b600081848411156129365760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561289357818101518382015260200161287b565b505050900390565b600080600061294d8686612a8f565b915091506000848061295b57fe5b86880990508281111561296f576001820391505b80830392508482106129c8576040805162461bcd60e51b815260206004820152601a60248201527f46756c6c4d6174683a3a6d756c4469763a206f766572666c6f77000000000000604482015290519081900360640190fd5b6129d3838387612abc565b979650505050505050565b6060612a33826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612b2c9092919063ffffffff16565b80519091501561270357808060200190516020811015612a5257600080fd5b50516127035760405162461bcd60e51b815260040180806020018281038252602a815260200180612df2602a913960400191505060405180910390fd5b6000808060001984860990508385029250828103915082811015612ab4576001820391505b509250929050565b60008181038216808381612acc57fe5b049250808581612ad857fe5b049450808160000381612ae757fe5b60028581038087028203028087028203028087028203028087028203028087028203028087028203029586029003909402930460010193909302939093010292915050565b6060612b3b8484600085612b43565b949350505050565b6060612b4e85612cb0565b612b9f576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b60208310612bde5780518252601f199092019160209182019101612bbf565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114612c40576040519150601f19603f3d011682016040523d82523d6000602084013e612c45565b606091505b50915091508115612c59579150612b3b9050565b805115612c695780518082602001fd5b60405162461bcd60e51b815260206004820181815286516024840152865187939192839260440191908501908083836000831561289357818101518382015260200161287b565b3b151590565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b6040805160208101909152600081529056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6c4669786564506f696e743a3a6672616374696f6e3a206469766973696f6e206279207a65726f56657374696e67206d757374206265206c6f6e676572207468616e20313030303020626c6f636b73536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572536c697070616765206c696d69743a206d6f7265207468616e206d61782070726963655361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220dfeb4d9044705c8c89935c4c73c1a1954073bcb35ba39600675af9a6e796b78164736f6c63430007050033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000fa1fbb8ef55a4855e5688c0ee13ac3f2024862860000000000000000000000001888bb30f9edd63b265942f3e3d061f186f38079000000000000000000000000e3f5a90f9cb311505cd691a46596599aa1a0ad7d0000000000000000000000005e983ff70de345de15dbdcf0529640f14446cdfa000000000000000000000000e3cd5475f18a97d3563307b4e1a64674702379270000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b180c7bbd35bae57d5eb4b4fc0516c4d50b5bf830000000000000000000000009dc084fd82860cdb4ed2b2bf59f1076f47b03bd6
-----Decoded View---------------
Arg [0] : _FHM (address): 0xfa1FBb8Ef55A4855E5688C0eE13aC3f202486286
Arg [1] : _sFHM (address): 0x1888BB30f9EdD63b265942F3E3D061F186f38079
Arg [2] : _principle (address): 0xE3F5a90F9cb311505cd691a46596599aA1A0AD7D
Arg [3] : _treasury (address): 0x5E983ff70DE345de15DbDCf0529640F14446cDfa
Arg [4] : _DAO (address): 0xE3CD5475f18a97D3563307B4e1A6467470237927
Arg [5] : _bondCalculator (address): 0x0000000000000000000000000000000000000000
Arg [6] : _fhudMinter (address): 0xB180c7BBd35bae57d5EB4B4fC0516c4d50b5BF83
Arg [7] : _fhmCirculatingSupply (address): 0x9DC084Fd82860cDb4ED2b2BF59F1076F47B03Bd6
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 000000000000000000000000fa1fbb8ef55a4855e5688c0ee13ac3f202486286
Arg [1] : 0000000000000000000000001888bb30f9edd63b265942f3e3d061f186f38079
Arg [2] : 000000000000000000000000e3f5a90f9cb311505cd691a46596599aa1a0ad7d
Arg [3] : 0000000000000000000000005e983ff70de345de15dbdcf0529640f14446cdfa
Arg [4] : 000000000000000000000000e3cd5475f18a97d3563307b4e1a6467470237927
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [6] : 000000000000000000000000b180c7bbd35bae57d5eb4b4fc0516c4d50b5bf83
Arg [7] : 0000000000000000000000009dc084fd82860cdb4ed2b2bf59f1076f47b03bd6
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$1.69
Net Worth in MOVR
Token Allocations
SFHM
100.00%
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| MOVR | 100.00% | $0.298946 | 5.6497 | $1.69 |
Loading...
Loading
Loading...
Loading
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.