Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x61238061 | 12442846 | 1169 days ago | IN | 0 ETH | 0.14966669 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
Swaps
Compiler Version
v0.7.3+commit.9bfce1f6
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: MIT pragma solidity ^0.7.3; import "./Assimilators.sol"; import "./Storage.sol"; import "./CurveMath.sol"; import "./UnsafeMath64x64.sol"; import "./ABDKMath64x64.sol"; import "./SafeMath.sol"; library Swaps { using ABDKMath64x64 for int128; using UnsafeMath64x64 for int128; using ABDKMath64x64 for uint256; using SafeMath for uint256; event Trade( address indexed trader, address indexed origin, address indexed target, uint256 originAmount, uint256 targetAmount ); int128 public constant ONE = 0x10000000000000000; function getOriginAndTarget( Storage.Curve storage curve, address _o, address _t ) private view returns (Storage.Assimilator memory, Storage.Assimilator memory) { Storage.Assimilator memory o_ = curve.assimilators[_o]; Storage.Assimilator memory t_ = curve.assimilators[_t]; require(o_.addr != address(0), "Curve/origin-not-supported"); require(t_.addr != address(0), "Curve/target-not-supported"); return (o_, t_); } function originSwap( Storage.Curve storage curve, address _origin, address _target, uint256 _originAmount, address _recipient ) external returns (uint256 tAmt_) { (Storage.Assimilator memory _o, Storage.Assimilator memory _t) = getOriginAndTarget(curve, _origin, _target); if (_o.ix == _t.ix) return Assimilators.outputNumeraire(_t.addr, _recipient, Assimilators.intakeRaw(_o.addr, _originAmount)); (int128 _amt, int128 _oGLiq, int128 _nGLiq, int128[] memory _oBals, int128[] memory _nBals) = getOriginSwapData(curve, _o.ix, _t.ix, _o.addr, _originAmount); _amt = CurveMath.calculateTrade(curve, _oGLiq, _nGLiq, _oBals, _nBals, _amt, _t.ix); _amt = _amt.us_mul(ONE - curve.epsilon); tAmt_ = Assimilators.outputNumeraire(_t.addr, _recipient, _amt); emit Trade(msg.sender, _origin, _target, _originAmount, tAmt_); } function viewOriginSwap( Storage.Curve storage curve, address _origin, address _target, uint256 _originAmount ) external view returns (uint256 tAmt_) { (Storage.Assimilator memory _o, Storage.Assimilator memory _t) = getOriginAndTarget(curve, _origin, _target); if (_o.ix == _t.ix) return Assimilators.viewRawAmount(_t.addr, Assimilators.viewNumeraireAmount(_o.addr, _originAmount)); (int128 _amt, int128 _oGLiq, int128 _nGLiq, int128[] memory _nBals, int128[] memory _oBals) = viewOriginSwapData(curve, _o.ix, _t.ix, _originAmount, _o.addr); _amt = CurveMath.calculateTrade(curve, _oGLiq, _nGLiq, _oBals, _nBals, _amt, _t.ix); _amt = _amt.us_mul(ONE - curve.epsilon); tAmt_ = Assimilators.viewRawAmount(_t.addr, _amt.abs()); } function targetSwap( Storage.Curve storage curve, address _origin, address _target, uint256 _targetAmount, address _recipient ) external returns (uint256 oAmt_) { (Storage.Assimilator memory _o, Storage.Assimilator memory _t) = getOriginAndTarget(curve, _origin, _target); if (_o.ix == _t.ix) return Assimilators.intakeNumeraire(_o.addr, Assimilators.outputRaw(_t.addr, _recipient, _targetAmount)); // If the origin is the quote currency (i.e. usdc) // we need to make sure to massage the _targetAmount // by dividing it by the exchange rate (so it gets // multiplied later to reach the same target amount). // Inelegant solution, but this way we don't need to // re-write large chunks of the code-base // curve.assets[1].addr = quoteCurrency // no variable assignment due to stack too deep if (curve.assets[1].addr == _o.addr) { _targetAmount = _targetAmount.mul(1e8).div(Assimilators.getRate(_t.addr)); } (int128 _amt, int128 _oGLiq, int128 _nGLiq, int128[] memory _oBals, int128[] memory _nBals) = getTargetSwapData(curve, _t.ix, _o.ix, _t.addr, _recipient, _targetAmount); _amt = CurveMath.calculateTrade(curve, _oGLiq, _nGLiq, _oBals, _nBals, _amt, _o.ix); // If the origin is the quote currency (i.e. usdc) // we need to make sure to massage the _amt too // curve.assets[1].addr = quoteCurrency if (curve.assets[1].addr == _o.addr) { _amt = _amt.mul(Assimilators.getRate(_t.addr).divu(1e8)); } _amt = _amt.us_mul(ONE + curve.epsilon); oAmt_ = Assimilators.intakeNumeraire(_o.addr, _amt); emit Trade(msg.sender, _origin, _target, oAmt_, _targetAmount); } function viewTargetSwap( Storage.Curve storage curve, address _origin, address _target, uint256 _targetAmount ) external view returns (uint256 oAmt_) { (Storage.Assimilator memory _o, Storage.Assimilator memory _t) = getOriginAndTarget(curve, _origin, _target); if (_o.ix == _t.ix) return Assimilators.viewRawAmount(_o.addr, Assimilators.viewNumeraireAmount(_t.addr, _targetAmount)); // If the origin is the quote currency (i.e. usdc) // we need to make sure to massage the _targetAmount // by dividing it by the exchange rate (so it gets // multiplied later to reach the same target amount). // Inelegant solution, but this way we don't need to // re-write large chunks of the code-base // curve.assets[1].addr = quoteCurrency // no variable assignment due to stack too deep if (curve.assets[1].addr == _o.addr) { _targetAmount = _targetAmount.mul(1e8).div(Assimilators.getRate(_t.addr)); } (int128 _amt, int128 _oGLiq, int128 _nGLiq, int128[] memory _nBals, int128[] memory _oBals) = viewTargetSwapData(curve, _t.ix, _o.ix, _targetAmount, _t.addr); _amt = CurveMath.calculateTrade(curve, _oGLiq, _nGLiq, _oBals, _nBals, _amt, _o.ix); // If the origin is the quote currency (i.e. usdc) // we need to make sure to massage the _amt too // curve.assets[1].addr = quoteCurrency if (curve.assets[1].addr == _o.addr) { _amt = _amt.mul(Assimilators.getRate(_t.addr).divu(1e8)); } _amt = _amt.us_mul(ONE + curve.epsilon); oAmt_ = Assimilators.viewRawAmount(_o.addr, _amt); } function getOriginSwapData( Storage.Curve storage curve, uint256 _inputIx, uint256 _outputIx, address _assim, uint256 _amt ) private returns ( int128 amt_, int128 oGLiq_, int128 nGLiq_, int128[] memory, int128[] memory ) { uint256 _length = curve.assets.length; int128[] memory oBals_ = new int128[](_length); int128[] memory nBals_ = new int128[](_length); Storage.Assimilator[] memory _reserves = curve.assets; for (uint256 i = 0; i < _length; i++) { if (i != _inputIx) nBals_[i] = oBals_[i] = Assimilators.viewNumeraireBalance(_reserves[i].addr); else { int128 _bal; (amt_, _bal) = Assimilators.intakeRawAndGetBalance(_assim, _amt); oBals_[i] = _bal.sub(amt_); nBals_[i] = _bal; } oGLiq_ += oBals_[i]; nGLiq_ += nBals_[i]; } nGLiq_ = nGLiq_.sub(amt_); nBals_[_outputIx] = ABDKMath64x64.sub(nBals_[_outputIx], amt_); return (amt_, oGLiq_, nGLiq_, oBals_, nBals_); } function getTargetSwapData( Storage.Curve storage curve, uint256 _inputIx, uint256 _outputIx, address _assim, address _recipient, uint256 _amt ) private returns ( int128 amt_, int128 oGLiq_, int128 nGLiq_, int128[] memory, int128[] memory ) { uint256 _length = curve.assets.length; int128[] memory oBals_ = new int128[](_length); int128[] memory nBals_ = new int128[](_length); Storage.Assimilator[] memory _reserves = curve.assets; for (uint256 i = 0; i < _length; i++) { if (i != _inputIx) nBals_[i] = oBals_[i] = Assimilators.viewNumeraireBalance(_reserves[i].addr); else { int128 _bal; (amt_, _bal) = Assimilators.outputRawAndGetBalance(_assim, _recipient, _amt); oBals_[i] = _bal.sub(amt_); nBals_[i] = _bal; } oGLiq_ += oBals_[i]; nGLiq_ += nBals_[i]; } nGLiq_ = nGLiq_.sub(amt_); nBals_[_outputIx] = ABDKMath64x64.sub(nBals_[_outputIx], amt_); return (amt_, oGLiq_, nGLiq_, oBals_, nBals_); } function viewOriginSwapData( Storage.Curve storage curve, uint256 _inputIx, uint256 _outputIx, uint256 _amt, address _assim ) private view returns ( int128 amt_, int128 oGLiq_, int128 nGLiq_, int128[] memory, int128[] memory ) { uint256 _length = curve.assets.length; int128[] memory nBals_ = new int128[](_length); int128[] memory oBals_ = new int128[](_length); for (uint256 i = 0; i < _length; i++) { if (i != _inputIx) nBals_[i] = oBals_[i] = Assimilators.viewNumeraireBalance(curve.assets[i].addr); else { int128 _bal; (amt_, _bal) = Assimilators.viewNumeraireAmountAndBalance(_assim, _amt); oBals_[i] = _bal; nBals_[i] = _bal.add(amt_); } oGLiq_ += oBals_[i]; nGLiq_ += nBals_[i]; } nGLiq_ = nGLiq_.sub(amt_); nBals_[_outputIx] = ABDKMath64x64.sub(nBals_[_outputIx], amt_); return (amt_, oGLiq_, nGLiq_, nBals_, oBals_); } function viewTargetSwapData( Storage.Curve storage curve, uint256 _inputIx, uint256 _outputIx, uint256 _amt, address _assim ) private view returns ( int128 amt_, int128 oGLiq_, int128 nGLiq_, int128[] memory, int128[] memory ) { uint256 _length = curve.assets.length; int128[] memory nBals_ = new int128[](_length); int128[] memory oBals_ = new int128[](_length); for (uint256 i = 0; i < _length; i++) { if (i != _inputIx) nBals_[i] = oBals_[i] = Assimilators.viewNumeraireBalance(curve.assets[i].addr); else { int128 _bal; (amt_, _bal) = Assimilators.viewNumeraireAmountAndBalance(_assim, _amt); amt_ = amt_.neg(); oBals_[i] = _bal; nBals_[i] = _bal.add(amt_); } oGLiq_ += oBals_[i]; nGLiq_ += nBals_[i]; } nGLiq_ = nGLiq_.sub(amt_); nBals_[_outputIx] = ABDKMath64x64.sub(nBals_[_outputIx], amt_); return (amt_, oGLiq_, nGLiq_, nBals_, oBals_); } }
// SPDX-License-Identifier: BSD-4-Clause /* * ABDK Math 64.64 Smart Contract Library. Copyright © 2019 by ABDK Consulting. * Author: Mikhail Vladimirov <[email protected]> */ pragma solidity ^0.7.0; /** * Smart contract library of mathematical functions operating with signed * 64.64-bit fixed point numbers. Signed 64.64-bit fixed point number is * basically a simple fraction whose numerator is signed 128-bit integer and * denominator is 2^64. As long as denominator is always the same, there is no * need to store it, thus in Solidity signed 64.64-bit fixed point numbers are * represented by int128 type holding only the numerator. */ library ABDKMath64x64 { /* * Minimum value signed 64.64-bit fixed point number may have. */ int128 private constant MIN_64x64 = -0x80000000000000000000000000000000; /* * Maximum value signed 64.64-bit fixed point number may have. */ int128 private constant MAX_64x64 = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; /** * Convert signed 256-bit integer number into signed 64.64-bit fixed point * number. Revert on overflow. * * @param x signed 256-bit integer number * @return signed 64.64-bit fixed point number */ function fromInt (int256 x) internal pure returns (int128) { require (x >= -0x8000000000000000 && x <= 0x7FFFFFFFFFFFFFFF); return int128 (x << 64); } /** * Convert signed 64.64 fixed point number into signed 64-bit integer number * rounding down. * * @param x signed 64.64-bit fixed point number * @return signed 64-bit integer number */ function toInt (int128 x) internal pure returns (int64) { return int64 (x >> 64); } /** * Convert unsigned 256-bit integer number into signed 64.64-bit fixed point * number. Revert on overflow. * * @param x unsigned 256-bit integer number * @return signed 64.64-bit fixed point number */ function fromUInt (uint256 x) internal pure returns (int128) { require (x <= 0x7FFFFFFFFFFFFFFF); return int128 (x << 64); } /** * Convert signed 64.64 fixed point number into unsigned 64-bit integer * number rounding down. Revert on underflow. * * @param x signed 64.64-bit fixed point number * @return unsigned 64-bit integer number */ function toUInt (int128 x) internal pure returns (uint64) { require (x >= 0); return uint64 (x >> 64); } /** * Convert signed 128.128 fixed point number into signed 64.64-bit fixed point * number rounding down. Revert on overflow. * * @param x signed 128.128-bin fixed point number * @return signed 64.64-bit fixed point number */ function from128x128 (int256 x) internal pure returns (int128) { int256 result = x >> 64; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } /** * Convert signed 64.64 fixed point number into signed 128.128 fixed point * number. * * @param x signed 64.64-bit fixed point number * @return signed 128.128 fixed point number */ function to128x128 (int128 x) internal pure returns (int256) { return int256 (x) << 64; } /** * Calculate x + y. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function add (int128 x, int128 y) internal pure returns (int128) { int256 result = int256(x) + y; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } /** * Calculate x - y. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function sub (int128 x, int128 y) internal pure returns (int128) { int256 result = int256(x) - y; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } /** * Calculate x * y rounding down. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function mul (int128 x, int128 y) internal pure returns (int128) { int256 result = int256(x) * y >> 64; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } /** * Calculate x * y rounding towards zero, where x is signed 64.64 fixed point * number and y is signed 256-bit integer number. Revert on overflow. * * @param x signed 64.64 fixed point number * @param y signed 256-bit integer number * @return signed 256-bit integer number */ function muli (int128 x, int256 y) internal pure returns (int256) { if (x == MIN_64x64) { require (y >= -0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF && y <= 0x1000000000000000000000000000000000000000000000000); return -y << 63; } else { bool negativeResult = false; if (x < 0) { x = -x; negativeResult = true; } if (y < 0) { y = -y; // We rely on overflow behavior here negativeResult = !negativeResult; } uint256 absoluteResult = mulu (x, uint256 (y)); if (negativeResult) { require (absoluteResult <= 0x8000000000000000000000000000000000000000000000000000000000000000); return -int256 (absoluteResult); // We rely on overflow behavior here } else { require (absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return int256 (absoluteResult); } } } /** * Calculate x * y rounding down, where x is signed 64.64 fixed point number * and y is unsigned 256-bit integer number. Revert on overflow. * * @param x signed 64.64 fixed point number * @param y unsigned 256-bit integer number * @return unsigned 256-bit integer number */ function mulu (int128 x, uint256 y) internal pure returns (uint256) { if (y == 0) return 0; require (x >= 0); uint256 lo = (uint256 (x) * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) >> 64; uint256 hi = uint256 (x) * (y >> 128); require (hi <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); hi <<= 64; require (hi <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - lo); return hi + lo; } /** * Calculate x / y rounding towards zero. Revert on overflow or when y is * zero. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function div (int128 x, int128 y) internal pure returns (int128) { require (y != 0); int256 result = (int256 (x) << 64) / y; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } /** * Calculate x / y rounding towards zero, where x and y are signed 256-bit * integer numbers. Revert on overflow or when y is zero. * * @param x signed 256-bit integer number * @param y signed 256-bit integer number * @return signed 64.64-bit fixed point number */ function divi (int256 x, int256 y) internal pure returns (int128) { require (y != 0); bool negativeResult = false; if (x < 0) { x = -x; // We rely on overflow behavior here negativeResult = true; } if (y < 0) { y = -y; // We rely on overflow behavior here negativeResult = !negativeResult; } uint128 absoluteResult = divuu (uint256 (x), uint256 (y)); if (negativeResult) { require (absoluteResult <= 0x80000000000000000000000000000000); return -int128 (absoluteResult); // We rely on overflow behavior here } else { require (absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return int128 (absoluteResult); // We rely on overflow behavior here } } /** * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit * integer numbers. Revert on overflow or when y is zero. * * @param x unsigned 256-bit integer number * @param y unsigned 256-bit integer number * @return signed 64.64-bit fixed point number */ function divu (uint256 x, uint256 y) internal pure returns (int128) { require (y != 0); uint128 result = divuu (x, y); require (result <= uint128 (MAX_64x64)); return int128 (result); } /** * Calculate -x. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function neg (int128 x) internal pure returns (int128) { require (x != MIN_64x64); return -x; } /** * Calculate |x|. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function abs (int128 x) internal pure returns (int128) { require (x != MIN_64x64); return x < 0 ? -x : x; } /** * Calculate 1 / x rounding towards zero. Revert on overflow or when x is * zero. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function inv (int128 x) internal pure returns (int128) { require (x != 0); int256 result = int256 (0x100000000000000000000000000000000) / x; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } /** * Calculate arithmetics average of x and y, i.e. (x + y) / 2 rounding down. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function avg (int128 x, int128 y) internal pure returns (int128) { return int128 ((int256 (x) + int256 (y)) >> 1); } /** * Calculate geometric average of x and y, i.e. sqrt (x * y) rounding down. * Revert on overflow or in case x * y is negative. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function gavg (int128 x, int128 y) internal pure returns (int128) { int256 m = int256 (x) * int256 (y); require (m >= 0); require (m < 0x4000000000000000000000000000000000000000000000000000000000000000); return int128 (sqrtu (uint256 (m))); } /** * Calculate x^y assuming 0^0 is 1, where x is signed 64.64 fixed point number * and y is unsigned 256-bit integer number. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @param y uint256 value * @return signed 64.64-bit fixed point number */ function pow (int128 x, uint256 y) internal pure returns (int128) { uint256 absoluteResult; bool negativeResult = false; if (x >= 0) { absoluteResult = powu (uint256 (x) << 63, y); } else { // We rely on overflow behavior here absoluteResult = powu (uint256 (uint128 (-x)) << 63, y); negativeResult = y & 1 > 0; } absoluteResult >>= 63; if (negativeResult) { require (absoluteResult <= 0x80000000000000000000000000000000); return -int128 (absoluteResult); // We rely on overflow behavior here } else { require (absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return int128 (absoluteResult); // We rely on overflow behavior here } } /** * Calculate sqrt (x) rounding down. Revert if x < 0. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function sqrt (int128 x) internal pure returns (int128) { require (x >= 0); return int128 (sqrtu (uint256 (x) << 64)); } /** * Calculate binary logarithm of x. Revert if x <= 0. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function log_2 (int128 x) internal pure returns (int128) { require (x > 0); int256 msb = 0; int256 xc = x; if (xc >= 0x10000000000000000) { xc >>= 64; msb += 64; } if (xc >= 0x100000000) { xc >>= 32; msb += 32; } if (xc >= 0x10000) { xc >>= 16; msb += 16; } if (xc >= 0x100) { xc >>= 8; msb += 8; } if (xc >= 0x10) { xc >>= 4; msb += 4; } if (xc >= 0x4) { xc >>= 2; msb += 2; } if (xc >= 0x2) msb += 1; // No need to shift xc anymore int256 result = msb - 64 << 64; uint256 ux = uint256 (x) << uint256 (127 - msb); for (int256 bit = 0x8000000000000000; bit > 0; bit >>= 1) { ux *= ux; uint256 b = ux >> 255; ux >>= 127 + b; result += bit * int256 (b); } return int128 (result); } /** * Calculate natural logarithm of x. Revert if x <= 0. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function ln (int128 x) internal pure returns (int128) { require (x > 0); return int128 ( uint256 (log_2 (x)) * 0xB17217F7D1CF79ABC9E3B39803F2F6AF >> 128); } /** * Calculate binary exponent of x. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function exp_2 (int128 x) internal pure returns (int128) { require (x < 0x400000000000000000); // Overflow if (x < -0x400000000000000000) return 0; // Underflow uint256 result = 0x80000000000000000000000000000000; if (x & 0x8000000000000000 > 0) result = result * 0x16A09E667F3BCC908B2FB1366EA957D3E >> 128; if (x & 0x4000000000000000 > 0) result = result * 0x1306FE0A31B7152DE8D5A46305C85EDEC >> 128; if (x & 0x2000000000000000 > 0) result = result * 0x1172B83C7D517ADCDF7C8C50EB14A791F >> 128; if (x & 0x1000000000000000 > 0) result = result * 0x10B5586CF9890F6298B92B71842A98363 >> 128; if (x & 0x800000000000000 > 0) result = result * 0x1059B0D31585743AE7C548EB68CA417FD >> 128; if (x & 0x400000000000000 > 0) result = result * 0x102C9A3E778060EE6F7CACA4F7A29BDE8 >> 128; if (x & 0x200000000000000 > 0) result = result * 0x10163DA9FB33356D84A66AE336DCDFA3F >> 128; if (x & 0x100000000000000 > 0) result = result * 0x100B1AFA5ABCBED6129AB13EC11DC9543 >> 128; if (x & 0x80000000000000 > 0) result = result * 0x10058C86DA1C09EA1FF19D294CF2F679B >> 128; if (x & 0x40000000000000 > 0) result = result * 0x1002C605E2E8CEC506D21BFC89A23A00F >> 128; if (x & 0x20000000000000 > 0) result = result * 0x100162F3904051FA128BCA9C55C31E5DF >> 128; if (x & 0x10000000000000 > 0) result = result * 0x1000B175EFFDC76BA38E31671CA939725 >> 128; if (x & 0x8000000000000 > 0) result = result * 0x100058BA01FB9F96D6CACD4B180917C3D >> 128; if (x & 0x4000000000000 > 0) result = result * 0x10002C5CC37DA9491D0985C348C68E7B3 >> 128; if (x & 0x2000000000000 > 0) result = result * 0x1000162E525EE054754457D5995292026 >> 128; if (x & 0x1000000000000 > 0) result = result * 0x10000B17255775C040618BF4A4ADE83FC >> 128; if (x & 0x800000000000 > 0) result = result * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB >> 128; if (x & 0x400000000000 > 0) result = result * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9 >> 128; if (x & 0x200000000000 > 0) result = result * 0x10000162E43F4F831060E02D839A9D16D >> 128; if (x & 0x100000000000 > 0) result = result * 0x100000B1721BCFC99D9F890EA06911763 >> 128; if (x & 0x80000000000 > 0) result = result * 0x10000058B90CF1E6D97F9CA14DBCC1628 >> 128; if (x & 0x40000000000 > 0) result = result * 0x1000002C5C863B73F016468F6BAC5CA2B >> 128; if (x & 0x20000000000 > 0) result = result * 0x100000162E430E5A18F6119E3C02282A5 >> 128; if (x & 0x10000000000 > 0) result = result * 0x1000000B1721835514B86E6D96EFD1BFE >> 128; if (x & 0x8000000000 > 0) result = result * 0x100000058B90C0B48C6BE5DF846C5B2EF >> 128; if (x & 0x4000000000 > 0) result = result * 0x10000002C5C8601CC6B9E94213C72737A >> 128; if (x & 0x2000000000 > 0) result = result * 0x1000000162E42FFF037DF38AA2B219F06 >> 128; if (x & 0x1000000000 > 0) result = result * 0x10000000B17217FBA9C739AA5819F44F9 >> 128; if (x & 0x800000000 > 0) result = result * 0x1000000058B90BFCDEE5ACD3C1CEDC823 >> 128; if (x & 0x400000000 > 0) result = result * 0x100000002C5C85FE31F35A6A30DA1BE50 >> 128; if (x & 0x200000000 > 0) result = result * 0x10000000162E42FF0999CE3541B9FFFCF >> 128; if (x & 0x100000000 > 0) result = result * 0x100000000B17217F80F4EF5AADDA45554 >> 128; if (x & 0x80000000 > 0) result = result * 0x10000000058B90BFBF8479BD5A81B51AD >> 128; if (x & 0x40000000 > 0) result = result * 0x1000000002C5C85FDF84BD62AE30A74CC >> 128; if (x & 0x20000000 > 0) result = result * 0x100000000162E42FEFB2FED257559BDAA >> 128; if (x & 0x10000000 > 0) result = result * 0x1000000000B17217F7D5A7716BBA4A9AE >> 128; if (x & 0x8000000 > 0) result = result * 0x100000000058B90BFBE9DDBAC5E109CCE >> 128; if (x & 0x4000000 > 0) result = result * 0x10000000002C5C85FDF4B15DE6F17EB0D >> 128; if (x & 0x2000000 > 0) result = result * 0x1000000000162E42FEFA494F1478FDE05 >> 128; if (x & 0x1000000 > 0) result = result * 0x10000000000B17217F7D20CF927C8E94C >> 128; if (x & 0x800000 > 0) result = result * 0x1000000000058B90BFBE8F71CB4E4B33D >> 128; if (x & 0x400000 > 0) result = result * 0x100000000002C5C85FDF477B662B26945 >> 128; if (x & 0x200000 > 0) result = result * 0x10000000000162E42FEFA3AE53369388C >> 128; if (x & 0x100000 > 0) result = result * 0x100000000000B17217F7D1D351A389D40 >> 128; if (x & 0x80000 > 0) result = result * 0x10000000000058B90BFBE8E8B2D3D4EDE >> 128; if (x & 0x40000 > 0) result = result * 0x1000000000002C5C85FDF4741BEA6E77E >> 128; if (x & 0x20000 > 0) result = result * 0x100000000000162E42FEFA39FE95583C2 >> 128; if (x & 0x10000 > 0) result = result * 0x1000000000000B17217F7D1CFB72B45E1 >> 128; if (x & 0x8000 > 0) result = result * 0x100000000000058B90BFBE8E7CC35C3F0 >> 128; if (x & 0x4000 > 0) result = result * 0x10000000000002C5C85FDF473E242EA38 >> 128; if (x & 0x2000 > 0) result = result * 0x1000000000000162E42FEFA39F02B772C >> 128; if (x & 0x1000 > 0) result = result * 0x10000000000000B17217F7D1CF7D83C1A >> 128; if (x & 0x800 > 0) result = result * 0x1000000000000058B90BFBE8E7BDCBE2E >> 128; if (x & 0x400 > 0) result = result * 0x100000000000002C5C85FDF473DEA871F >> 128; if (x & 0x200 > 0) result = result * 0x10000000000000162E42FEFA39EF44D91 >> 128; if (x & 0x100 > 0) result = result * 0x100000000000000B17217F7D1CF79E949 >> 128; if (x & 0x80 > 0) result = result * 0x10000000000000058B90BFBE8E7BCE544 >> 128; if (x & 0x40 > 0) result = result * 0x1000000000000002C5C85FDF473DE6ECA >> 128; if (x & 0x20 > 0) result = result * 0x100000000000000162E42FEFA39EF366F >> 128; if (x & 0x10 > 0) result = result * 0x1000000000000000B17217F7D1CF79AFA >> 128; if (x & 0x8 > 0) result = result * 0x100000000000000058B90BFBE8E7BCD6D >> 128; if (x & 0x4 > 0) result = result * 0x10000000000000002C5C85FDF473DE6B2 >> 128; if (x & 0x2 > 0) result = result * 0x1000000000000000162E42FEFA39EF358 >> 128; if (x & 0x1 > 0) result = result * 0x10000000000000000B17217F7D1CF79AB >> 128; result >>= uint256 (63 - (x >> 64)); require (result <= uint256 (MAX_64x64)); return int128 (result); } /** * Calculate natural exponent of x. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function exp (int128 x) internal pure returns (int128) { require (x < 0x400000000000000000); // Overflow if (x < -0x400000000000000000) return 0; // Underflow return exp_2 ( int128 (int256 (x) * 0x171547652B82FE1777D0FFDA0D23A7D12 >> 128)); } /** * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit * integer numbers. Revert on overflow or when y is zero. * * @param x unsigned 256-bit integer number * @param y unsigned 256-bit integer number * @return unsigned 64.64-bit fixed point number */ function divuu (uint256 x, uint256 y) private pure returns (uint128) { require (y != 0); uint256 result; if (x <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) result = (x << 64) / y; else { uint256 msb = 192; uint256 xc = x >> 192; if (xc >= 0x100000000) { xc >>= 32; msb += 32; } if (xc >= 0x10000) { xc >>= 16; msb += 16; } if (xc >= 0x100) { xc >>= 8; msb += 8; } if (xc >= 0x10) { xc >>= 4; msb += 4; } if (xc >= 0x4) { xc >>= 2; msb += 2; } if (xc >= 0x2) msb += 1; // No need to shift xc anymore result = (x << 255 - msb) / ((y - 1 >> msb - 191) + 1); require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); uint256 hi = result * (y >> 128); uint256 lo = result * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); uint256 xh = x >> 192; uint256 xl = x << 64; if (xl < lo) xh -= 1; xl -= lo; // We rely on overflow behavior here lo = hi << 128; if (xl < lo) xh -= 1; xl -= lo; // We rely on overflow behavior here assert (xh == hi >> 128); result += xl / y; } require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return uint128 (result); } /** * Calculate x^y assuming 0^0 is 1, where x is unsigned 129.127 fixed point * number and y is unsigned 256-bit integer number. Revert on overflow. * * @param x unsigned 129.127-bit fixed point number * @param y uint256 value * @return unsigned 129.127-bit fixed point number */ function powu (uint256 x, uint256 y) private pure returns (uint256) { if (y == 0) return 0x80000000000000000000000000000000; else if (x == 0) return 0; else { int256 msb = 0; uint256 xc = x; if (xc >= 0x100000000000000000000000000000000) { xc >>= 128; msb += 128; } if (xc >= 0x10000000000000000) { xc >>= 64; msb += 64; } if (xc >= 0x100000000) { xc >>= 32; msb += 32; } if (xc >= 0x10000) { xc >>= 16; msb += 16; } if (xc >= 0x100) { xc >>= 8; msb += 8; } if (xc >= 0x10) { xc >>= 4; msb += 4; } if (xc >= 0x4) { xc >>= 2; msb += 2; } if (xc >= 0x2) msb += 1; // No need to shift xc anymore int256 xe = msb - 127; if (xe > 0) x >>= uint256 (xe); else x <<= uint256 (-xe); uint256 result = 0x80000000000000000000000000000000; int256 re = 0; while (y > 0) { if (y & 1 > 0) { result = result * x; y -= 1; re += xe; if (result >= 0x8000000000000000000000000000000000000000000000000000000000000000) { result >>= 128; re += 1; } else result >>= 127; if (re < -127) return 0; // Underflow require (re < 128); // Overflow } else { x = x * x; y >>= 1; xe <<= 1; if (x >= 0x8000000000000000000000000000000000000000000000000000000000000000) { x >>= 128; xe += 1; } else x >>= 127; if (xe < -127) return 0; // Underflow require (xe < 128); // Overflow } } if (re > 0) result <<= uint256 (re); else if (re < 0) result >>= uint256 (-re); return result; } } /** * Calculate sqrt (x) rounding down, where x is unsigned 256-bit integer * number. * * @param x unsigned 256-bit integer number * @return unsigned 128-bit integer number */ function sqrtu (uint256 x) private pure returns (uint128) { if (x == 0) return 0; else { uint256 xx = x; uint256 r = 1; if (xx >= 0x100000000000000000000000000000000) { xx >>= 128; r <<= 64; } if (xx >= 0x10000000000000000) { xx >>= 64; r <<= 32; } if (xx >= 0x100000000) { xx >>= 32; r <<= 16; } if (xx >= 0x10000) { xx >>= 16; r <<= 8; } if (xx >= 0x100) { xx >>= 8; r <<= 4; } if (xx >= 0x10) { xx >>= 4; r <<= 2; } if (xx >= 0x8) { r <<= 1; } r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; // Seven iterations should be enough uint256 r1 = x / r; return uint128 (r < r1 ? r : r1); } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // 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"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(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 { // 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); } } } }
// SPDX-License-Identifier: MIT // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.7.3; import "./Address.sol"; import "./IAssimilator.sol"; import "./ABDKMath64x64.sol"; library Assimilators { using ABDKMath64x64 for int128; using Address for address; IAssimilator public constant iAsmltr = IAssimilator(address(0)); function delegate(address _callee, bytes memory _data) internal returns (bytes memory) { require(_callee.isContract(), "Assimilators/callee-is-not-a-contract"); // solhint-disable-next-line (bool _success, bytes memory returnData_) = _callee.delegatecall(_data); // solhint-disable-next-line assembly { if eq(_success, 0) { revert(add(returnData_, 0x20), returndatasize()) } } return returnData_; } function getRate(address _assim) internal view returns (uint256 amount_) { amount_ = IAssimilator(_assim).getRate(); } function viewRawAmount(address _assim, int128 _amt) internal view returns (uint256 amount_) { amount_ = IAssimilator(_assim).viewRawAmount(_amt); } function viewRawAmountLPRatio( address _assim, uint256 _baseWeight, uint256 _quoteWeight, int128 _amount ) internal view returns (uint256 amount_) { amount_ = IAssimilator(_assim).viewRawAmountLPRatio(_baseWeight, _quoteWeight, address(this), _amount); } function viewNumeraireAmount(address _assim, uint256 _amt) internal view returns (int128 amt_) { amt_ = IAssimilator(_assim).viewNumeraireAmount(_amt); } function viewNumeraireAmountAndBalance(address _assim, uint256 _amt) internal view returns (int128 amt_, int128 bal_) { (amt_, bal_) = IAssimilator(_assim).viewNumeraireAmountAndBalance(address(this), _amt); } function viewNumeraireBalance(address _assim) internal view returns (int128 bal_) { bal_ = IAssimilator(_assim).viewNumeraireBalance(address(this)); } function viewNumeraireBalanceLPRatio( uint256 _baseWeight, uint256 _quoteWeight, address _assim ) internal view returns (int128 bal_) { bal_ = IAssimilator(_assim).viewNumeraireBalanceLPRatio(_baseWeight, _quoteWeight, address(this)); } function intakeRaw(address _assim, uint256 _amt) internal returns (int128 amt_) { bytes memory data = abi.encodeWithSelector(iAsmltr.intakeRaw.selector, _amt); amt_ = abi.decode(delegate(_assim, data), (int128)); } function intakeRawAndGetBalance(address _assim, uint256 _amt) internal returns (int128 amt_, int128 bal_) { bytes memory data = abi.encodeWithSelector(iAsmltr.intakeRawAndGetBalance.selector, _amt); (amt_, bal_) = abi.decode(delegate(_assim, data), (int128, int128)); } function intakeNumeraire(address _assim, int128 _amt) internal returns (uint256 amt_) { bytes memory data = abi.encodeWithSelector(iAsmltr.intakeNumeraire.selector, _amt); amt_ = abi.decode(delegate(_assim, data), (uint256)); } function intakeNumeraireLPRatio( address _assim, uint256 _baseWeight, uint256 _quoteWeight, int128 _amount ) internal returns (uint256 amt_) { bytes memory data = abi.encodeWithSelector( iAsmltr.intakeNumeraireLPRatio.selector, _baseWeight, _quoteWeight, address(this), _amount ); amt_ = abi.decode(delegate(_assim, data), (uint256)); } function outputRaw( address _assim, address _dst, uint256 _amt ) internal returns (int128 amt_) { bytes memory data = abi.encodeWithSelector(iAsmltr.outputRaw.selector, _dst, _amt); amt_ = abi.decode(delegate(_assim, data), (int128)); amt_ = amt_.neg(); } function outputRawAndGetBalance( address _assim, address _dst, uint256 _amt ) internal returns (int128 amt_, int128 bal_) { bytes memory data = abi.encodeWithSelector(iAsmltr.outputRawAndGetBalance.selector, _dst, _amt); (amt_, bal_) = abi.decode(delegate(_assim, data), (int128, int128)); amt_ = amt_.neg(); } function outputNumeraire( address _assim, address _dst, int128 _amt ) internal returns (uint256 amt_) { bytes memory data = abi.encodeWithSelector(iAsmltr.outputNumeraire.selector, _dst, _amt.abs()); amt_ = abi.decode(delegate(_assim, data), (uint256)); } }
// SPDX-License-Identifier: MIT // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.7.3; import "./Storage.sol"; import "./UnsafeMath64x64.sol"; import "./ABDKMath64x64.sol"; library CurveMath { int128 private constant ONE = 0x10000000000000000; int128 private constant MAX = 0x4000000000000000; // .25 in layman's terms int128 private constant MAX_DIFF = -0x10C6F7A0B5EE; int128 private constant ONE_WEI = 0x12; using ABDKMath64x64 for int128; using UnsafeMath64x64 for int128; using ABDKMath64x64 for uint256; // This is used to prevent stack too deep errors function calculateFee( int128 _gLiq, int128[] memory _bals, Storage.Curve storage curve, int128[] memory _weights ) internal view returns (int128 psi_) { int128 _beta = curve.beta; int128 _delta = curve.delta; psi_ = calculateFee(_gLiq, _bals, _beta, _delta, _weights); } function calculateFee( int128 _gLiq, int128[] memory _bals, int128 _beta, int128 _delta, int128[] memory _weights ) internal pure returns (int128 psi_) { uint256 _length = _bals.length; for (uint256 i = 0; i < _length; i++) { int128 _ideal = _gLiq.mul(_weights[i]); psi_ += calculateMicroFee(_bals[i], _ideal, _beta, _delta); } } function calculateMicroFee( int128 _bal, int128 _ideal, int128 _beta, int128 _delta ) private pure returns (int128 fee_) { if (_bal < _ideal) { int128 _threshold = _ideal.mul(ONE - _beta); if (_bal < _threshold) { int128 _feeMargin = _threshold - _bal; fee_ = _feeMargin.div(_ideal); fee_ = fee_.mul(_delta); if (fee_ > MAX) fee_ = MAX; fee_ = fee_.mul(_feeMargin); } else fee_ = 0; } else { int128 _threshold = _ideal.mul(ONE + _beta); if (_bal > _threshold) { int128 _feeMargin = _bal - _threshold; fee_ = _feeMargin.div(_ideal); fee_ = fee_.mul(_delta); if (fee_ > MAX) fee_ = MAX; fee_ = fee_.mul(_feeMargin); } else fee_ = 0; } } function calculateTrade( Storage.Curve storage curve, int128 _oGLiq, int128 _nGLiq, int128[] memory _oBals, int128[] memory _nBals, int128 _inputAmt, uint256 _outputIndex ) internal view returns (int128 outputAmt_) { outputAmt_ = -_inputAmt; int128 _lambda = curve.lambda; int128[] memory _weights = curve.weights; int128 _omega = calculateFee(_oGLiq, _oBals, curve, _weights); int128 _psi; for (uint256 i = 0; i < 32; i++) { _psi = calculateFee(_nGLiq, _nBals, curve, _weights); int128 prevAmount; { prevAmount = outputAmt_; outputAmt_ = _omega < _psi ? -(_inputAmt + _omega - _psi) : -(_inputAmt + _lambda.mul(_omega - _psi)); } if (outputAmt_ / 1e13 == prevAmount / 1e13) { _nGLiq = _oGLiq + _inputAmt + outputAmt_; _nBals[_outputIndex] = _oBals[_outputIndex] + outputAmt_; enforceHalts(curve, _oGLiq, _nGLiq, _oBals, _nBals, _weights); enforceSwapInvariant(_oGLiq, _omega, _nGLiq, _psi); return outputAmt_; } else { _nGLiq = _oGLiq + _inputAmt + outputAmt_; _nBals[_outputIndex] = _oBals[_outputIndex].add(outputAmt_); } } revert("Curve/swap-convergence-failed"); } function calculateLiquidityMembrane( Storage.Curve storage curve, int128 _oGLiq, int128 _nGLiq, int128[] memory _oBals, int128[] memory _nBals ) internal view returns (int128 curves_) { enforceHalts(curve, _oGLiq, _nGLiq, _oBals, _nBals, curve.weights); int128 _omega; int128 _psi; { int128 _beta = curve.beta; int128 _delta = curve.delta; int128[] memory _weights = curve.weights; _omega = calculateFee(_oGLiq, _oBals, _beta, _delta, _weights); _psi = calculateFee(_nGLiq, _nBals, _beta, _delta, _weights); } int128 _feeDiff = _psi.sub(_omega); int128 _liqDiff = _nGLiq.sub(_oGLiq); int128 _oUtil = _oGLiq.sub(_omega); int128 _totalShells = curve.totalSupply.divu(1e18); int128 _curveMultiplier; if (_totalShells == 0) { curves_ = _nGLiq.sub(_psi); } else if (_feeDiff >= 0) { _curveMultiplier = _liqDiff.sub(_feeDiff).div(_oUtil); } else { _curveMultiplier = _liqDiff.sub(curve.lambda.mul(_feeDiff)); _curveMultiplier = _curveMultiplier.div(_oUtil); } if (_totalShells != 0) { curves_ = _totalShells.mul(_curveMultiplier); enforceLiquidityInvariant(_totalShells, curves_, _oGLiq, _nGLiq, _omega, _psi); } } function enforceSwapInvariant( int128 _oGLiq, int128 _omega, int128 _nGLiq, int128 _psi ) private pure { int128 _nextUtil = _nGLiq - _psi; int128 _prevUtil = _oGLiq - _omega; int128 _diff = _nextUtil - _prevUtil; require(0 < _diff || _diff >= MAX_DIFF, "Curve/swap-invariant-violation"); } function enforceLiquidityInvariant( int128 _totalShells, int128 _newShells, int128 _oGLiq, int128 _nGLiq, int128 _omega, int128 _psi ) internal pure { if (_totalShells == 0 || 0 == _totalShells + _newShells) return; int128 _prevUtilPerShell = _oGLiq.sub(_omega).div(_totalShells); int128 _nextUtilPerShell = _nGLiq.sub(_psi).div(_totalShells.add(_newShells)); int128 _diff = _nextUtilPerShell - _prevUtilPerShell; require(0 < _diff || _diff >= MAX_DIFF, "Curve/liquidity-invariant-violation"); } function enforceHalts( Storage.Curve storage curve, int128 _oGLiq, int128 _nGLiq, int128[] memory _oBals, int128[] memory _nBals, int128[] memory _weights ) private view { uint256 _length = _nBals.length; int128 _alpha = curve.alpha; for (uint256 i = 0; i < _length; i++) { int128 _nIdeal = _nGLiq.mul(_weights[i]); if (_nBals[i] > _nIdeal) { int128 _upperAlpha = ONE + _alpha; int128 _nHalt = _nIdeal.mul(_upperAlpha); if (_nBals[i] > _nHalt) { int128 _oHalt = _oGLiq.mul(_weights[i]).mul(_upperAlpha); if (_oBals[i] < _oHalt) revert("Curve/upper-halt"); if (_nBals[i] - _nHalt > _oBals[i] - _oHalt) revert("Curve/upper-halt"); } } else { int128 _lowerAlpha = ONE - _alpha; int128 _nHalt = _nIdeal.mul(_lowerAlpha); if (_nBals[i] < _nHalt) { int128 _oHalt = _oGLiq.mul(_weights[i]); _oHalt = _oHalt.mul(_lowerAlpha); if (_oBals[i] > _oHalt) revert("Curve/lower-halt"); if (_nHalt - _nBals[i] > _oHalt - _oBals[i]) revert("Curve/lower-halt"); } } } } }
// SPDX-License-Identifier: MIT // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.7.3; interface IAssimilator { function getRate() external view returns (uint256); function intakeRaw(uint256 amount) external returns (int128); function intakeRawAndGetBalance(uint256 amount) external returns (int128, int128); function intakeNumeraire(int128 amount) external returns (uint256); function intakeNumeraireLPRatio( uint256, uint256, address, int128 ) external returns (uint256); function outputRaw(address dst, uint256 amount) external returns (int128); function outputRawAndGetBalance(address dst, uint256 amount) external returns (int128, int128); function outputNumeraire(address dst, int128 amount) external returns (uint256); function viewRawAmount(int128) external view returns (uint256); function viewRawAmountLPRatio( uint256, uint256, address, int128 ) external view returns (uint256); function viewNumeraireAmount(uint256) external view returns (int128); function viewNumeraireBalanceLPRatio( uint256, uint256, address ) external view returns (int128); function viewNumeraireBalance(address) external view returns (int128); function viewNumeraireAmountAndBalance(address, uint256) external view returns (int128, int128); }
// SPDX-License-Identifier: MIT // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.7.3; interface IOracle { function acceptOwnership() external; function accessController() external view returns (address); function aggregator() external view returns (address); function confirmAggregator(address _aggregator) external; function decimals() external view returns (uint8); function description() external view returns (string memory); function getAnswer(uint256 _roundId) external view returns (int256); function getRoundData(uint80 _roundId) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function getTimestamp(uint256 _roundId) external view returns (uint256); function latestAnswer() external view returns (int256); function latestRound() external view returns (uint256); function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function latestTimestamp() external view returns (uint256); function owner() external view returns (address); function phaseAggregators(uint16) external view returns (address); function phaseId() external view returns (uint16); function proposeAggregator(address _aggregator) external; function proposedAggregator() external view returns (address); function proposedGetRoundData(uint80 _roundId) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function proposedLatestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function setController(address _accessController) external; function transferOwnership(address _to) external; function version() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.7.3; import "./IOracle.sol"; import "./Assimilators.sol"; contract Storage { struct Curve { // Curve parameters int128 alpha; int128 beta; int128 delta; int128 epsilon; int128 lambda; int128[] weights; // Assets and their assimilators Assimilator[] assets; mapping(address => Assimilator) assimilators; // Oracles to determine the price // Note that 0'th index should always be USDC 1e18 // Oracle's pricing should be denominated in Currency/USDC mapping(address => IOracle) oracles; // ERC20 Interface uint256 totalSupply; mapping(address => uint256) balances; mapping(address => mapping(address => uint256)) allowances; } struct Assimilator { address addr; uint8 ix; } // Curve parameters Curve public curve; // Ownable address public owner; string public name_; string public symbol_; address[] public derivatives; address[] public numeraires; address[] public reserves; // Curve operational state bool public frozen = false; bool public emergency = false; bool public whitelistingStage = true; bool internal notEntered = true; mapping(address => uint256) public whitelistedDeposited; }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.3; library UnsafeMath64x64 { /** * Calculate x * y rounding down. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function us_mul (int128 x, int128 y) internal pure returns (int128) { int256 result = int256(x) * y >> 64; return int128 (result); } /** * Calculate x / y rounding towards zero. Revert on overflow or when y is * zero. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function us_div (int128 x, int128 y) internal pure returns (int128) { int256 result = (int256 (x) << 64) / y; return int128 (result); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"trader","type":"address"},{"indexed":true,"internalType":"address","name":"origin","type":"address"},{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"uint256","name":"originAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"targetAmount","type":"uint256"}],"name":"Trade","type":"event"},{"inputs":[],"name":"ONE","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
612380610026600b82828239805160001a60731461001957fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100615760003560e01c806356fa0ba4146100665780639eeb3404146100b4578063c2ee3a0814610103578063cc3b6a7314610122578063fb7455da14610171575b600080fd5b6100a26004803603608081101561007c57600080fd5b508035906001600160a01b036020820135811691604081013590911690606001356101ad565b60408051918252519081900360200190f35b8180156100c057600080fd5b506100a2600480360360a08110156100d757600080fd5b508035906001600160a01b03602082013581169160408101358216916060820135916080013516610358565b61010b6104a2565b60408051600f9290920b8252519081900360200190f35b81801561012e57600080fd5b506100a2600480360360a081101561014557600080fd5b508035906001600160a01b036020820135811691604081013582169160608201359160800135166104aa565b6100a26004803603608081101561018757600080fd5b508035906001600160a01b03602082013581169160408101359091169060600135610694565b60006101b76122ed565b6101bf6122ed565b6101ca878787610761565b91509150806020015160ff16826020015160ff16141561020557815181516101fc91906101f790876108bb565b610934565b92505050610350565b81600001516001600160a01b03168760040160018154811061022357fe5b6000918252602090912001546001600160a01b031614156102655761026261024e826000015161097d565b61025c866305f5e1006109ea565b90610a4c565b93505b600080600060608061028c8c876020015160ff16896020015160ff168c8a60000151610a8e565b945094509450945094506102ac8c858584868a8d6020015160ff16610cb9565b945086600001516001600160a01b03168c6004016001815481106102cc57fe5b6000918252602090912001546001600160a01b03161415610313576103106103056305f5e1006102ff896000015161097d565b90610eea565b600f87900b90610f21565b94505b60018c015461033690600f87810b91600160801b9004900b600160401b01610f58565b9450610346876000015186610934565b9750505050505050505b949350505050565b60006103626122ed565b61036a6122ed565b610375888888610761565b91509150806020015160ff16826020015160ff1614156103b4576103ab8160000151856103a6856000015189610f66565b610fc9565b92505050610499565b60008060006060806103db8d886020015160ff16886020015160ff168a600001518e611064565b945094509450945094506103fb8d858585858a8c6020015160ff16610cb9565b60018e015490955061042190600f87810b91600160801b9004900b600160401b03610f58565b945061043286600001518a87610fc9565b97508a6001600160a01b03168c6001600160a01b0316336001600160a01b03167fec0d3e799aa270a144d7e3be084ccfc657450e33ecea1b1a4154c95cedaae5c38d8c604051808381526020018281526020019250505060405180910390a4505050505050505b95945050505050565b600160401b81565b60006104b46122ed565b6104bc6122ed565b6104c7888888610761565b91509150806020015160ff16826020015160ff1614156104fa57815181516103ab91906104f59087896112ed565b611366565b81600001516001600160a01b03168860040160018154811061051857fe5b6000918252602090912001546001600160a01b0316141561055457610551610543826000015161097d565b61025c876305f5e1006109ea565b94505b600080600060608061057c8d876020015160ff16896020015160ff1689600001518d8f6113b0565b9450945094509450945061059c8d858585858a8d6020015160ff16610cb9565b945086600001516001600160a01b03168d6004016001815481106105bc57fe5b6000918252602090912001546001600160a01b031614156105f2576105ef6103056305f5e1006102ff896000015161097d565b94505b60018d015461061590600f87810b91600160801b9004900b600160401b01610f58565b9450610625876000015186611366565b97508a6001600160a01b03168c6001600160a01b0316336001600160a01b03167fec0d3e799aa270a144d7e3be084ccfc657450e33ecea1b1a4154c95cedaae5c38b8e604051808381526020018281526020019250505060405180910390a45050505050505095945050505050565b600061069e6122ed565b6106a66122ed565b6106b1878787610761565b91509150806020015160ff16826020015160ff1614156106de57805182516101fc91906101f790876108bb565b60008060006060806107058c886020015160ff16886020015160ff168c8b6000015161161c565b945094509450945094506107258c858584868a8c6020015160ff16610cb9565b60018d015490955061074b90600f87810b91600160801b9004900b600160401b03610f58565b945061034686600001516101f787600f0b6117bf565b6107696122ed565b6107716122ed565b6107796122ed565b506001600160a01b0384811660009081526005870160209081526040918290208251808401909352549283168252600160a01b90920460ff16918101919091526107c16122ed565b506001600160a01b0384811660009081526005880160209081526040918290208251808401909352548084168352600160a01b900460ff16908201528251909116610853576040805162461bcd60e51b815260206004820152601a60248201527f43757276652f6f726967696e2d6e6f742d737570706f72746564000000000000604482015290519081900360640190fd5b80516001600160a01b03166108af576040805162461bcd60e51b815260206004820152601a60248201527f43757276652f7461726765742d6e6f742d737570706f72746564000000000000604482015290519081900360640190fd5b90969095509350505050565b6000826001600160a01b031663f5e6c0ca836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561090157600080fd5b505afa158015610915573d6000803e3d6000fd5b505050506040513d602081101561092b57600080fd5b50519392505050565b6000826001600160a01b0316636b677a8f836040518263ffffffff1660e01b81526004018082600f0b815260200191505060206040518083038186803b15801561090157600080fd5b6000816001600160a01b031663679aefce6040518163ffffffff1660e01b815260040160206040518083038186803b1580156109b857600080fd5b505afa1580156109cc573d6000803e3d6000fd5b505050506040513d60208110156109e257600080fd5b505192915050565b6000826109f957506000610a46565b82820282848281610a0657fe5b0414610a435760405162461bcd60e51b81526004018080602001828103825260218152602001806123056021913960400191505060405180910390fd5b90505b92915050565b6000610a4383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506117f2565b6004850154600090819081906060908190818167ffffffffffffffff81118015610ab757600080fd5b50604051908082528060200260200182016040528015610ae1578160200160208202803683370190505b50905060608267ffffffffffffffff81118015610afd57600080fd5b50604051908082528060200260200182016040528015610b27578160200160208202803683370190505b50905060005b83811015610c57578c8114610bac57610b688e6004018281548110610b4e57fe5b6000918252602090912001546001600160a01b0316611894565b828281518110610b7457fe5b6020026020010190600f0b9081600f0b815250838281518110610b9357fe5b6020026020010190600f0b9081600f0b81525050610c1a565b6000610bb88b8d6118e3565b909a509050610bca600f8b900b611971565b995080838381518110610bd957fe5b600f92830b830b6020918202929092010152610bf89082900b8b61198c565b848381518110610c0457fe5b6020026020010190600f0b9081600f0b81525050505b818181518110610c2657fe5b602002602001015188019750828181518110610c3e57fe5b6020026020010151870196508080600101915050610b2d565b50610c66600f87900b896119bf565b9550610c85828c81518110610c7757fe5b6020026020010151896119bf565b828c81518110610c9157fe5b600f92830b90920b602092830291909101909101529093509150509550955095509550959050565b600287015460038801805460408051602080840282018101909252828152600087900394600f0b936060939192909190830182828015610d3e57602002820191906000526020600020906000905b82829054906101000a9004600f0b600f0b81526020019060100190602082600f01049283019260010382029150808411610d075790505b505050505090506000610d538a898d856119f2565b90506000805b6020811015610e9157610d6e8b8a8f876119f2565b915085600f83810b9085900b12610d9957610d8f600f87900b848603610f21565b8901600003610da2565b82848a01036000035b96506509184e72a00081600f0b81610db657fe5b05600f0b6509184e72a00088600f0b81610dcc57fe5b05600f0b1415610e385786898e01019b50868b8981518110610dea57fe5b6020026020010151018a8981518110610dff57fe5b6020026020010190600f0b9081600f0b81525050610e218e8e8e8e8e8a611a18565b610e2d8d858e86611d38565b505050505050610edf565b86898e01019b50610e68878c8a81518110610e4f57fe5b6020026020010151600f0b61198c90919063ffffffff16565b8a8981518110610e7457fe5b6020026020010190600f0b9081600f0b8152505050600101610d59565b506040805162461bcd60e51b815260206004820152601d60248201527f43757276652f737761702d636f6e76657267656e63652d6661696c6564000000604482015290519081900360640190fd5b979650505050505050565b600081610ef657600080fd5b6000610f028484611db9565b905060016001607f1b036001600160801b0382161115610a4357600080fd5b6000600f83810b9083900b0260401d60016001607f1b03198112801590610f4f575060016001607f1b038113155b610a4357600080fd5b600f91820b910b0260401d90565b6040805160248082018490528251808303909101815260449091019091526020810180516001600160e01b0316637d00081560e11b179052600090610fab8482611f03565b8060200190516020811015610fbf57600080fd5b5051949350505050565b600060606337e1c82960e11b84610fe3600f86900b6117bf565b60405160240180836001600160a01b0316815260200182600f0b815260200192505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505090506110458582611f03565b806020019051602081101561105957600080fd5b505195945050505050565b6004850154600090819081906060908190818167ffffffffffffffff8111801561108d57600080fd5b506040519080825280602002602001820160405280156110b7578160200160208202803683370190505b50905060608267ffffffffffffffff811180156110d357600080fd5b506040519080825280602002602001820160405280156110fd578160200160208202803683370190505b50905060608d600401805480602002602001604051908101604052809291908181526020016000905b8282101561116f57600084815260209081902060408051808201909152908401546001600160a01b0381168252600160a01b900460ff1681830152825260019092019101611126565b50505050905060005b8481101561128a578d81146111eb576111a782828151811061119657fe5b602002602001015160000151611894565b8482815181106111b357fe5b6020026020010190600f0b9081600f0b8152508382815181106111d257fe5b6020026020010190600f0b9081600f0b8152505061124d565b60006111f78d8d61200a565b909b50905061120a600f82900b8c6119bf565b85838151811061121657fe5b6020026020010190600f0b9081600f0b815250508084838151811061123757fe5b6020026020010190600f0b9081600f0b81525050505b83818151811061125957fe5b60200260200101518901985082818151811061127157fe5b6020026020010151880197508080600101915050611178565b50611299600f88900b8a6119bf565b96506112b8828d815181106112aa57fe5b60200260200101518a6119bf565b828d815181106112c457fe5b600f92830b90920b60209283029190910190910152509093509150509550955095509550959050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663f09a3fc360e01b1790526000906113418582611f03565b806020019051602081101561135557600080fd5b50519150610499600f83900b611971565b60408051600f83900b6024808301919091528251808303909101815260449091019091526020810180516001600160e01b0316624e387960e31b179052600090610fab8482611f03565b6004860154600090819081906060908190818167ffffffffffffffff811180156113d957600080fd5b50604051908082528060200260200182016040528015611403578160200160208202803683370190505b50905060608267ffffffffffffffff8111801561141f57600080fd5b50604051908082528060200260200182016040528015611449578160200160208202803683370190505b50905060608e600401805480602002602001604051908101604052809291908181526020016000905b828210156114bb57600084815260209081902060408051808201909152908401546001600160a01b0381168252600160a01b900460ff1681830152825260019092019101611472565b50505050905060005b848110156115c6578e8114611526576114e282828151811061119657fe5b8482815181106114ee57fe5b6020026020010190600f0b9081600f0b81525083828151811061150d57fe5b6020026020010190600f0b9081600f0b81525050611589565b60006115338e8e8e61207a565b909b509050611546600f82900b8c6119bf565b85838151811061155257fe5b6020026020010190600f0b9081600f0b815250508084838151811061157357fe5b6020026020010190600f0b9081600f0b81525050505b83818151811061159557fe5b6020026020010151890198508281815181106115ad57fe5b60200260200101518801975080806001019150506114c4565b506115d5600f88900b8a6119bf565b96506115e6828e815181106112aa57fe5b828e815181106115f257fe5b600f92830b90920b6020928302919091019091015250909350915050965096509650965096915050565b6004850154600090819081906060908190818167ffffffffffffffff8111801561164557600080fd5b5060405190808252806020026020018201604052801561166f578160200160208202803683370190505b50905060608267ffffffffffffffff8111801561168b57600080fd5b506040519080825280602002602001820160405280156116b5578160200160208202803683370190505b50905060005b83811015610c57578c8114611720576116dc8e6004018281548110610b4e57fe5b8282815181106116e857fe5b6020026020010190600f0b9081600f0b81525083828151811061170757fe5b6020026020010190600f0b9081600f0b81525050611782565b600061172c8b8d6118e3565b809250819b5050508083838151811061174157fe5b600f92830b830b60209182029290920101526117609082900b8b61198c565b84838151811061176c57fe5b6020026020010190600f0b9081600f0b81525050505b81818151811061178e57fe5b6020026020010151880197508281815181106117a657fe5b60200260200101518701965080806001019150506116bb565b6000600f82900b60016001607f1b031914156117da57600080fd5b600082600f0b126117eb5781610a46565b5060000390565b6000818361187e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561184357818101518382015260200161182b565b50505050905090810190601f1680156118705780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161188a57fe5b0495945050505050565b6000816001600160a01b031663ac969a73306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156109b857600080fd5b60408051630f4d965d60e11b815230600482015260248101839052815160009283926001600160a01b03871692631e9b2cba92604480840193919291829003018186803b15801561193357600080fd5b505afa158015611947573d6000803e3d6000fd5b505050506040513d604081101561195d57600080fd5b508051602090910151909590945092505050565b6000600f82900b60016001607f1b031914156117eb57600080fd5b6000600f83810b9083900b0160016001607f1b03198112801590610f4f575060016001607f1b03811315610a4357600080fd5b6000600f82810b9084900b0360016001607f1b03198112801590610f4f575060016001607f1b03811315610a4357600080fd5b81546001830154600091600160801b9004600f90810b91900b610edf878784848861210a565b81518654600f0b60005b82811015611d2d576000611a55858381518110611a3b57fe5b602002602001015189600f0b610f2190919063ffffffff16565b905080600f0b868381518110611a6757fe5b6020026020010151600f0b1315611bce57600160401b83016000611a8f600f84900b83610f21565b905080600f0b888581518110611aa157fe5b6020026020010151600f0b1315611bc7576000611aea83611ae18a8881518110611ac757fe5b60200260200101518f600f0b610f2190919063ffffffff16565b600f0b90610f21565b905080600f0b8a8681518110611afc57fe5b6020026020010151600f0b1215611b4d576040805162461bcd60e51b815260206004820152601060248201526f10dd5c9d994bdd5c1c195c8b5a185b1d60821b604482015290519081900360640190fd5b808a8681518110611b5a57fe5b602002602001015103600f0b828a8781518110611b7357fe5b602002602001015103600f0b1315611bc5576040805162461bcd60e51b815260206004820152601060248201526f10dd5c9d994bdd5c1c195c8b5a185b1d60821b604482015290519081900360640190fd5b505b5050611d24565b600160401b8390036000611be6600f84900b83610f21565b905080600f0b888581518110611bf857fe5b6020026020010151600f0b1215611d21576000611c34888681518110611c1a57fe5b60200260200101518d600f0b610f2190919063ffffffff16565b9050611c44600f82900b84610f21565b905080600f0b8a8681518110611c5657fe5b6020026020010151600f0b1315611ca7576040805162461bcd60e51b815260206004820152601060248201526f10dd5c9d994bdb1bddd95c8b5a185b1d60821b604482015290519081900360640190fd5b898581518110611cb357fe5b60200260200101518103600f0b898681518110611ccc57fe5b60200260200101518303600f0b1315611d1f576040805162461bcd60e51b815260206004820152601060248201526f10dd5c9d994bdb1bddd95c8b5a185b1d60821b604482015290519081900360640190fd5b505b50505b50600101611a22565b505050505050505050565b808203838503808203600f81900b60001280611d5f57506510c6f7a0b5ed19600f82900b12155b611db0576040805162461bcd60e51b815260206004820152601e60248201527f43757276652f737761702d696e76617269616e742d76696f6c6174696f6e0000604482015290519081900360640190fd5b50505050505050565b600081611dc557600080fd5b60006001600160c01b038411611dea5782604085901b81611de257fe5b049050611eef565b60c084811c6401000000008110611e03576020918201911c5b620100008110611e15576010918201911c5b6101008110611e26576008918201911c5b60108110611e36576004918201911c5b60048110611e46576002918201911c5b60028110611e55576001820191505b60bf820360018603901c6001018260ff0387901b81611e7057fe5b0492506001600160801b03831115611e8757600080fd5b608085901c83026001600160801b038616840260c088901c604089901b82811015611eb3576001820391505b608084901b92900382811015611eca576001820391505b829003608084901c8214611eda57fe5b888181611ee357fe5b04870196505050505050505b6001600160801b03811115610a4357600080fd5b6060611f17836001600160a01b031661217d565b611f525760405162461bcd60e51b81526004018080602001828103825260258152602001806123266025913960400191505060405180910390fd5b60006060846001600160a01b0316846040518082805190602001908083835b60208310611f905780518252601f199092019160209182019101611f71565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d8060008114611ff0576040519150601f19603f3d011682016040523d82523d6000602084013e611ff5565b606091505b50915091506000821415610350573d60208201fd5b6040805160248082018490528251808303909101815260449091019091526020810180516001600160e01b0316631fcca3b360e21b17905260009081906120518582611f03565b806020019051604081101561206557600080fd5b50805160209091015190969095509350505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663523bf25760e01b17905260009081906120d08682611f03565b80602001905160408110156120e457600080fd5b50805160209091015190935091506120ff600f84900b611971565b925050935093915050565b8351600090815b8181101561217257600061214485838151811061212a57fe5b60200260200101518a600f0b610f2190919063ffffffff16565b905061216588838151811061215557fe5b6020026020010151828989612183565b9093019250600101612111565b505095945050505050565b3b151590565b600083600f0b85600f0b12156122165760006121aa600f86900b600160401b869003610f21565b905080600f0b86600f0b121561220b578581036121cb600f82900b8761229b565b92506121db600f84900b85610f21565b92506001603e1b600f84900b13156121f5576001603e1b92505b612203600f84900b82610f21565b925050612210565b600091505b50610350565b600061222c600f86900b600160401b8601610f21565b905080600f0b86600f0b131561228d5780860361224d600f82900b8761229b565b925061225d600f84900b85610f21565b92506001603e1b600f84900b1315612277576001603e1b92505b612285600f84900b82610f21565b925050612292565b600091505b50949350505050565b600081600f0b600014156122ae57600080fd5b600082600f0b604085600f0b901b816122c357fe5b05905060016001607f1b03198112801590610f4f575060016001607f1b03811315610a4357600080fd5b60408051808201909152600080825260208201529056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77417373696d696c61746f72732f63616c6c65652d69732d6e6f742d612d636f6e7472616374a264697066735822122066ab6675d9d0ae62d37d2fc77135afce24e2ce55a5af45333cb16a6dc968037b64736f6c63430007030033
Deployed Bytecode
0x732b2bfe80547f50e1a67bbf0d52c24e0683f67b6d30146080604052600436106100615760003560e01c806356fa0ba4146100665780639eeb3404146100b4578063c2ee3a0814610103578063cc3b6a7314610122578063fb7455da14610171575b600080fd5b6100a26004803603608081101561007c57600080fd5b508035906001600160a01b036020820135811691604081013590911690606001356101ad565b60408051918252519081900360200190f35b8180156100c057600080fd5b506100a2600480360360a08110156100d757600080fd5b508035906001600160a01b03602082013581169160408101358216916060820135916080013516610358565b61010b6104a2565b60408051600f9290920b8252519081900360200190f35b81801561012e57600080fd5b506100a2600480360360a081101561014557600080fd5b508035906001600160a01b036020820135811691604081013582169160608201359160800135166104aa565b6100a26004803603608081101561018757600080fd5b508035906001600160a01b03602082013581169160408101359091169060600135610694565b60006101b76122ed565b6101bf6122ed565b6101ca878787610761565b91509150806020015160ff16826020015160ff16141561020557815181516101fc91906101f790876108bb565b610934565b92505050610350565b81600001516001600160a01b03168760040160018154811061022357fe5b6000918252602090912001546001600160a01b031614156102655761026261024e826000015161097d565b61025c866305f5e1006109ea565b90610a4c565b93505b600080600060608061028c8c876020015160ff16896020015160ff168c8a60000151610a8e565b945094509450945094506102ac8c858584868a8d6020015160ff16610cb9565b945086600001516001600160a01b03168c6004016001815481106102cc57fe5b6000918252602090912001546001600160a01b03161415610313576103106103056305f5e1006102ff896000015161097d565b90610eea565b600f87900b90610f21565b94505b60018c015461033690600f87810b91600160801b9004900b600160401b01610f58565b9450610346876000015186610934565b9750505050505050505b949350505050565b60006103626122ed565b61036a6122ed565b610375888888610761565b91509150806020015160ff16826020015160ff1614156103b4576103ab8160000151856103a6856000015189610f66565b610fc9565b92505050610499565b60008060006060806103db8d886020015160ff16886020015160ff168a600001518e611064565b945094509450945094506103fb8d858585858a8c6020015160ff16610cb9565b60018e015490955061042190600f87810b91600160801b9004900b600160401b03610f58565b945061043286600001518a87610fc9565b97508a6001600160a01b03168c6001600160a01b0316336001600160a01b03167fec0d3e799aa270a144d7e3be084ccfc657450e33ecea1b1a4154c95cedaae5c38d8c604051808381526020018281526020019250505060405180910390a4505050505050505b95945050505050565b600160401b81565b60006104b46122ed565b6104bc6122ed565b6104c7888888610761565b91509150806020015160ff16826020015160ff1614156104fa57815181516103ab91906104f59087896112ed565b611366565b81600001516001600160a01b03168860040160018154811061051857fe5b6000918252602090912001546001600160a01b0316141561055457610551610543826000015161097d565b61025c876305f5e1006109ea565b94505b600080600060608061057c8d876020015160ff16896020015160ff1689600001518d8f6113b0565b9450945094509450945061059c8d858585858a8d6020015160ff16610cb9565b945086600001516001600160a01b03168d6004016001815481106105bc57fe5b6000918252602090912001546001600160a01b031614156105f2576105ef6103056305f5e1006102ff896000015161097d565b94505b60018d015461061590600f87810b91600160801b9004900b600160401b01610f58565b9450610625876000015186611366565b97508a6001600160a01b03168c6001600160a01b0316336001600160a01b03167fec0d3e799aa270a144d7e3be084ccfc657450e33ecea1b1a4154c95cedaae5c38b8e604051808381526020018281526020019250505060405180910390a45050505050505095945050505050565b600061069e6122ed565b6106a66122ed565b6106b1878787610761565b91509150806020015160ff16826020015160ff1614156106de57805182516101fc91906101f790876108bb565b60008060006060806107058c886020015160ff16886020015160ff168c8b6000015161161c565b945094509450945094506107258c858584868a8c6020015160ff16610cb9565b60018d015490955061074b90600f87810b91600160801b9004900b600160401b03610f58565b945061034686600001516101f787600f0b6117bf565b6107696122ed565b6107716122ed565b6107796122ed565b506001600160a01b0384811660009081526005870160209081526040918290208251808401909352549283168252600160a01b90920460ff16918101919091526107c16122ed565b506001600160a01b0384811660009081526005880160209081526040918290208251808401909352548084168352600160a01b900460ff16908201528251909116610853576040805162461bcd60e51b815260206004820152601a60248201527f43757276652f6f726967696e2d6e6f742d737570706f72746564000000000000604482015290519081900360640190fd5b80516001600160a01b03166108af576040805162461bcd60e51b815260206004820152601a60248201527f43757276652f7461726765742d6e6f742d737570706f72746564000000000000604482015290519081900360640190fd5b90969095509350505050565b6000826001600160a01b031663f5e6c0ca836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561090157600080fd5b505afa158015610915573d6000803e3d6000fd5b505050506040513d602081101561092b57600080fd5b50519392505050565b6000826001600160a01b0316636b677a8f836040518263ffffffff1660e01b81526004018082600f0b815260200191505060206040518083038186803b15801561090157600080fd5b6000816001600160a01b031663679aefce6040518163ffffffff1660e01b815260040160206040518083038186803b1580156109b857600080fd5b505afa1580156109cc573d6000803e3d6000fd5b505050506040513d60208110156109e257600080fd5b505192915050565b6000826109f957506000610a46565b82820282848281610a0657fe5b0414610a435760405162461bcd60e51b81526004018080602001828103825260218152602001806123056021913960400191505060405180910390fd5b90505b92915050565b6000610a4383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506117f2565b6004850154600090819081906060908190818167ffffffffffffffff81118015610ab757600080fd5b50604051908082528060200260200182016040528015610ae1578160200160208202803683370190505b50905060608267ffffffffffffffff81118015610afd57600080fd5b50604051908082528060200260200182016040528015610b27578160200160208202803683370190505b50905060005b83811015610c57578c8114610bac57610b688e6004018281548110610b4e57fe5b6000918252602090912001546001600160a01b0316611894565b828281518110610b7457fe5b6020026020010190600f0b9081600f0b815250838281518110610b9357fe5b6020026020010190600f0b9081600f0b81525050610c1a565b6000610bb88b8d6118e3565b909a509050610bca600f8b900b611971565b995080838381518110610bd957fe5b600f92830b830b6020918202929092010152610bf89082900b8b61198c565b848381518110610c0457fe5b6020026020010190600f0b9081600f0b81525050505b818181518110610c2657fe5b602002602001015188019750828181518110610c3e57fe5b6020026020010151870196508080600101915050610b2d565b50610c66600f87900b896119bf565b9550610c85828c81518110610c7757fe5b6020026020010151896119bf565b828c81518110610c9157fe5b600f92830b90920b602092830291909101909101529093509150509550955095509550959050565b600287015460038801805460408051602080840282018101909252828152600087900394600f0b936060939192909190830182828015610d3e57602002820191906000526020600020906000905b82829054906101000a9004600f0b600f0b81526020019060100190602082600f01049283019260010382029150808411610d075790505b505050505090506000610d538a898d856119f2565b90506000805b6020811015610e9157610d6e8b8a8f876119f2565b915085600f83810b9085900b12610d9957610d8f600f87900b848603610f21565b8901600003610da2565b82848a01036000035b96506509184e72a00081600f0b81610db657fe5b05600f0b6509184e72a00088600f0b81610dcc57fe5b05600f0b1415610e385786898e01019b50868b8981518110610dea57fe5b6020026020010151018a8981518110610dff57fe5b6020026020010190600f0b9081600f0b81525050610e218e8e8e8e8e8a611a18565b610e2d8d858e86611d38565b505050505050610edf565b86898e01019b50610e68878c8a81518110610e4f57fe5b6020026020010151600f0b61198c90919063ffffffff16565b8a8981518110610e7457fe5b6020026020010190600f0b9081600f0b8152505050600101610d59565b506040805162461bcd60e51b815260206004820152601d60248201527f43757276652f737761702d636f6e76657267656e63652d6661696c6564000000604482015290519081900360640190fd5b979650505050505050565b600081610ef657600080fd5b6000610f028484611db9565b905060016001607f1b036001600160801b0382161115610a4357600080fd5b6000600f83810b9083900b0260401d60016001607f1b03198112801590610f4f575060016001607f1b038113155b610a4357600080fd5b600f91820b910b0260401d90565b6040805160248082018490528251808303909101815260449091019091526020810180516001600160e01b0316637d00081560e11b179052600090610fab8482611f03565b8060200190516020811015610fbf57600080fd5b5051949350505050565b600060606337e1c82960e11b84610fe3600f86900b6117bf565b60405160240180836001600160a01b0316815260200182600f0b815260200192505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505090506110458582611f03565b806020019051602081101561105957600080fd5b505195945050505050565b6004850154600090819081906060908190818167ffffffffffffffff8111801561108d57600080fd5b506040519080825280602002602001820160405280156110b7578160200160208202803683370190505b50905060608267ffffffffffffffff811180156110d357600080fd5b506040519080825280602002602001820160405280156110fd578160200160208202803683370190505b50905060608d600401805480602002602001604051908101604052809291908181526020016000905b8282101561116f57600084815260209081902060408051808201909152908401546001600160a01b0381168252600160a01b900460ff1681830152825260019092019101611126565b50505050905060005b8481101561128a578d81146111eb576111a782828151811061119657fe5b602002602001015160000151611894565b8482815181106111b357fe5b6020026020010190600f0b9081600f0b8152508382815181106111d257fe5b6020026020010190600f0b9081600f0b8152505061124d565b60006111f78d8d61200a565b909b50905061120a600f82900b8c6119bf565b85838151811061121657fe5b6020026020010190600f0b9081600f0b815250508084838151811061123757fe5b6020026020010190600f0b9081600f0b81525050505b83818151811061125957fe5b60200260200101518901985082818151811061127157fe5b6020026020010151880197508080600101915050611178565b50611299600f88900b8a6119bf565b96506112b8828d815181106112aa57fe5b60200260200101518a6119bf565b828d815181106112c457fe5b600f92830b90920b60209283029190910190910152509093509150509550955095509550959050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663f09a3fc360e01b1790526000906113418582611f03565b806020019051602081101561135557600080fd5b50519150610499600f83900b611971565b60408051600f83900b6024808301919091528251808303909101815260449091019091526020810180516001600160e01b0316624e387960e31b179052600090610fab8482611f03565b6004860154600090819081906060908190818167ffffffffffffffff811180156113d957600080fd5b50604051908082528060200260200182016040528015611403578160200160208202803683370190505b50905060608267ffffffffffffffff8111801561141f57600080fd5b50604051908082528060200260200182016040528015611449578160200160208202803683370190505b50905060608e600401805480602002602001604051908101604052809291908181526020016000905b828210156114bb57600084815260209081902060408051808201909152908401546001600160a01b0381168252600160a01b900460ff1681830152825260019092019101611472565b50505050905060005b848110156115c6578e8114611526576114e282828151811061119657fe5b8482815181106114ee57fe5b6020026020010190600f0b9081600f0b81525083828151811061150d57fe5b6020026020010190600f0b9081600f0b81525050611589565b60006115338e8e8e61207a565b909b509050611546600f82900b8c6119bf565b85838151811061155257fe5b6020026020010190600f0b9081600f0b815250508084838151811061157357fe5b6020026020010190600f0b9081600f0b81525050505b83818151811061159557fe5b6020026020010151890198508281815181106115ad57fe5b60200260200101518801975080806001019150506114c4565b506115d5600f88900b8a6119bf565b96506115e6828e815181106112aa57fe5b828e815181106115f257fe5b600f92830b90920b6020928302919091019091015250909350915050965096509650965096915050565b6004850154600090819081906060908190818167ffffffffffffffff8111801561164557600080fd5b5060405190808252806020026020018201604052801561166f578160200160208202803683370190505b50905060608267ffffffffffffffff8111801561168b57600080fd5b506040519080825280602002602001820160405280156116b5578160200160208202803683370190505b50905060005b83811015610c57578c8114611720576116dc8e6004018281548110610b4e57fe5b8282815181106116e857fe5b6020026020010190600f0b9081600f0b81525083828151811061170757fe5b6020026020010190600f0b9081600f0b81525050611782565b600061172c8b8d6118e3565b809250819b5050508083838151811061174157fe5b600f92830b830b60209182029290920101526117609082900b8b61198c565b84838151811061176c57fe5b6020026020010190600f0b9081600f0b81525050505b81818151811061178e57fe5b6020026020010151880197508281815181106117a657fe5b60200260200101518701965080806001019150506116bb565b6000600f82900b60016001607f1b031914156117da57600080fd5b600082600f0b126117eb5781610a46565b5060000390565b6000818361187e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561184357818101518382015260200161182b565b50505050905090810190601f1680156118705780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161188a57fe5b0495945050505050565b6000816001600160a01b031663ac969a73306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156109b857600080fd5b60408051630f4d965d60e11b815230600482015260248101839052815160009283926001600160a01b03871692631e9b2cba92604480840193919291829003018186803b15801561193357600080fd5b505afa158015611947573d6000803e3d6000fd5b505050506040513d604081101561195d57600080fd5b508051602090910151909590945092505050565b6000600f82900b60016001607f1b031914156117eb57600080fd5b6000600f83810b9083900b0160016001607f1b03198112801590610f4f575060016001607f1b03811315610a4357600080fd5b6000600f82810b9084900b0360016001607f1b03198112801590610f4f575060016001607f1b03811315610a4357600080fd5b81546001830154600091600160801b9004600f90810b91900b610edf878784848861210a565b81518654600f0b60005b82811015611d2d576000611a55858381518110611a3b57fe5b602002602001015189600f0b610f2190919063ffffffff16565b905080600f0b868381518110611a6757fe5b6020026020010151600f0b1315611bce57600160401b83016000611a8f600f84900b83610f21565b905080600f0b888581518110611aa157fe5b6020026020010151600f0b1315611bc7576000611aea83611ae18a8881518110611ac757fe5b60200260200101518f600f0b610f2190919063ffffffff16565b600f0b90610f21565b905080600f0b8a8681518110611afc57fe5b6020026020010151600f0b1215611b4d576040805162461bcd60e51b815260206004820152601060248201526f10dd5c9d994bdd5c1c195c8b5a185b1d60821b604482015290519081900360640190fd5b808a8681518110611b5a57fe5b602002602001015103600f0b828a8781518110611b7357fe5b602002602001015103600f0b1315611bc5576040805162461bcd60e51b815260206004820152601060248201526f10dd5c9d994bdd5c1c195c8b5a185b1d60821b604482015290519081900360640190fd5b505b5050611d24565b600160401b8390036000611be6600f84900b83610f21565b905080600f0b888581518110611bf857fe5b6020026020010151600f0b1215611d21576000611c34888681518110611c1a57fe5b60200260200101518d600f0b610f2190919063ffffffff16565b9050611c44600f82900b84610f21565b905080600f0b8a8681518110611c5657fe5b6020026020010151600f0b1315611ca7576040805162461bcd60e51b815260206004820152601060248201526f10dd5c9d994bdb1bddd95c8b5a185b1d60821b604482015290519081900360640190fd5b898581518110611cb357fe5b60200260200101518103600f0b898681518110611ccc57fe5b60200260200101518303600f0b1315611d1f576040805162461bcd60e51b815260206004820152601060248201526f10dd5c9d994bdb1bddd95c8b5a185b1d60821b604482015290519081900360640190fd5b505b50505b50600101611a22565b505050505050505050565b808203838503808203600f81900b60001280611d5f57506510c6f7a0b5ed19600f82900b12155b611db0576040805162461bcd60e51b815260206004820152601e60248201527f43757276652f737761702d696e76617269616e742d76696f6c6174696f6e0000604482015290519081900360640190fd5b50505050505050565b600081611dc557600080fd5b60006001600160c01b038411611dea5782604085901b81611de257fe5b049050611eef565b60c084811c6401000000008110611e03576020918201911c5b620100008110611e15576010918201911c5b6101008110611e26576008918201911c5b60108110611e36576004918201911c5b60048110611e46576002918201911c5b60028110611e55576001820191505b60bf820360018603901c6001018260ff0387901b81611e7057fe5b0492506001600160801b03831115611e8757600080fd5b608085901c83026001600160801b038616840260c088901c604089901b82811015611eb3576001820391505b608084901b92900382811015611eca576001820391505b829003608084901c8214611eda57fe5b888181611ee357fe5b04870196505050505050505b6001600160801b03811115610a4357600080fd5b6060611f17836001600160a01b031661217d565b611f525760405162461bcd60e51b81526004018080602001828103825260258152602001806123266025913960400191505060405180910390fd5b60006060846001600160a01b0316846040518082805190602001908083835b60208310611f905780518252601f199092019160209182019101611f71565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d8060008114611ff0576040519150601f19603f3d011682016040523d82523d6000602084013e611ff5565b606091505b50915091506000821415610350573d60208201fd5b6040805160248082018490528251808303909101815260449091019091526020810180516001600160e01b0316631fcca3b360e21b17905260009081906120518582611f03565b806020019051604081101561206557600080fd5b50805160209091015190969095509350505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663523bf25760e01b17905260009081906120d08682611f03565b80602001905160408110156120e457600080fd5b50805160209091015190935091506120ff600f84900b611971565b925050935093915050565b8351600090815b8181101561217257600061214485838151811061212a57fe5b60200260200101518a600f0b610f2190919063ffffffff16565b905061216588838151811061215557fe5b6020026020010151828989612183565b9093019250600101612111565b505095945050505050565b3b151590565b600083600f0b85600f0b12156122165760006121aa600f86900b600160401b869003610f21565b905080600f0b86600f0b121561220b578581036121cb600f82900b8761229b565b92506121db600f84900b85610f21565b92506001603e1b600f84900b13156121f5576001603e1b92505b612203600f84900b82610f21565b925050612210565b600091505b50610350565b600061222c600f86900b600160401b8601610f21565b905080600f0b86600f0b131561228d5780860361224d600f82900b8761229b565b925061225d600f84900b85610f21565b92506001603e1b600f84900b1315612277576001603e1b92505b612285600f84900b82610f21565b925050612292565b600091505b50949350505050565b600081600f0b600014156122ae57600080fd5b600082600f0b604085600f0b901b816122c357fe5b05905060016001607f1b03198112801590610f4f575060016001607f1b03811315610a4357600080fd5b60408051808201909152600080825260208201529056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77417373696d696c61746f72732f63616c6c65652d69732d6e6f742d612d636f6e7472616374a264697066735822122066ab6675d9d0ae62d37d2fc77135afce24e2ce55a5af45333cb16a6dc968037b64736f6c63430007030033
Deployed Bytecode Sourcemap
226:11119:8:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4772:1732;;;;;;;;;;;;;;;;-1:-1:-1;4772:1732:8;;;-1:-1:-1;;;;;4772:1732:8;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;1122:947;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1122:947:8;;;-1:-1:-1;;;;;1122:947:8;;;;;;;;;;;;;;;;;;;;;;;;:::i;570:48::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;2925:1841;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2925:1841:8;;;-1:-1:-1;;;;;2925:1841:8;;;;;;;;;;;;;;;;;;;;;;;;:::i;2075:844::-;;;;;;;;;;;;;;;;-1:-1:-1;2075:844:8;;;-1:-1:-1;;;;;2075:844:8;;;;;;;;;;;;;;;;;;;:::i;4772:1732::-;4943:13;4969:29;;:::i;:::-;5000;;:::i;:::-;5033:43;5052:5;5059:7;5068;5033:18;:43::i;:::-;4968:108;;;;5100:2;:5;;;5091:14;;:2;:5;;;:14;;;5087:132;;;5153:7;;5195;;5126:93;;5153:7;5162:56;;5204:13;5162:32;:56::i;:::-;5126:26;:93::i;:::-;5119:100;;;;;;5087:132;5715:2;:7;;;-1:-1:-1;;;;;5691:31:8;:5;:12;;5704:1;5691:15;;;;;;;;;;;;;;;;;:20;-1:-1:-1;;;;;5691:20:8;:31;5687:135;;;5754:57;5781:29;5802:2;:7;;;5781:20;:29::i;:::-;5754:22;:13;5772:3;5754:17;:22::i;:::-;:26;;:57::i;:::-;5738:73;;5687:135;5833:11;5846:13;5861;5876:22;5900;5938:63;5957:5;5964:2;:5;;;5938:63;;5971:2;:5;;;5938:63;;5978:13;5993:2;:7;;;5938:18;:63::i;:::-;5832:169;;;;;;;;;;6019:76;6044:5;6051:6;6059;6067;6075;6083:4;6089:2;:5;;;6019:76;;:24;:76::i;:::-;6012:83;;6298:2;:7;;;-1:-1:-1;;;;;6274:31:8;:5;:12;;6287:1;6274:15;;;;;;;;;;;;;;;;;:20;-1:-1:-1;;;;;6274:20:8;:31;6270:118;;;6328:49;6337:39;6372:3;6337:29;6358:2;:7;;;6337:20;:29::i;:::-;:34;;:39::i;:::-;6328:8;;;;;;:49::i;:::-;6321:56;;6270:118;6423:13;;;;6405:32;;6423:13;6405:11;;;;-1:-1:-1;;;6423:13:8;;;;-1:-1:-1;;;6417:19:8;6405:11;:32::i;:::-;6398:39;;6456:41;6483:2;:7;;;6492:4;6456:26;:41::i;:::-;6448:49;;4772:1732;;;;;;;;;;;;;;:::o;1122:947::-;1312:13;1338:29;;:::i;:::-;1369;;:::i;:::-;1402:43;1421:5;1428:7;1437;1402:18;:43::i;:::-;1337:108;;;;1469:2;:5;;;1460:14;;:2;:5;;;:14;;;1456:136;;;1495:97;1524:2;:7;;;1533:10;1545:46;1568:2;:7;;;1577:13;1545:22;:46::i;:::-;1495:28;:97::i;:::-;1488:104;;;;;;1456:136;1604:11;1617:13;1632;1647:22;1671;1709:62;1727:5;1734:2;:5;;;1709:62;;1741:2;:5;;;1709:62;;1748:2;:7;;;1757:13;1709:17;:62::i;:::-;1603:168;;;;;;;;;;1789:76;1814:5;1821:6;1829;1837;1845;1853:4;1859:2;:5;;;1789:76;;:24;:76::i;:::-;1901:13;;;;1782:83;;-1:-1:-1;1883:32:8;;1901:13;1883:11;;;;-1:-1:-1;;;1901:13:8;;;;-1:-1:-1;;;1895:19:8;1883:11;:32::i;:::-;1876:39;;1934:55;1963:2;:7;;;1972:10;1984:4;1934:28;:55::i;:::-;1926:63;;2032:7;-1:-1:-1;;;;;2005:57:8;2023:7;-1:-1:-1;;;;;2005:57:8;2011:10;-1:-1:-1;;;;;2005:57:8;;2041:13;2056:5;2005:57;;;;;;;;;;;;;;;;;;;;;;;;1122:947;;;;;;;;;;;;;;;:::o;570:48::-;-1:-1:-1;;;570:48:8;:::o;2925:1841::-;3115:13;3141:29;;:::i;:::-;3172;;:::i;:::-;3205:43;3224:5;3231:7;3240;3205:18;:43::i;:::-;3140:108;;;;3272:2;:5;;;3263:14;;:2;:5;;;:14;;;3259:136;;;3327:7;;3359;;3298:97;;3327:7;3336:58;;3368:10;3380:13;3336:22;:58::i;:::-;3298:28;:97::i;3259:136::-;3891:2;:7;;;-1:-1:-1;;;;;3867:31:8;:5;:12;;3880:1;3867:15;;;;;;;;;;;;;;;;;:20;-1:-1:-1;;;;;3867:20:8;:31;3863:135;;;3930:57;3957:29;3978:2;:7;;;3957:20;:29::i;:::-;3930:22;:13;3948:3;3930:17;:22::i;:57::-;3914:73;;3863:135;4009:11;4022:13;4037;4052:22;4076;4114:74;4132:5;4139:2;:5;;;4114:74;;4146:2;:5;;;4114:74;;4153:2;:7;;;4162:10;4174:13;4114:17;:74::i;:::-;4008:180;;;;;;;;;;4206:76;4231:5;4238:6;4246;4254;4262;4270:4;4276:2;:5;;;4206:76;;:24;:76::i;:::-;4199:83;;4485:2;:7;;;-1:-1:-1;;;;;4461:31:8;:5;:12;;4474:1;4461:15;;;;;;;;;;;;;;;;;:20;-1:-1:-1;;;;;4461:20:8;:31;4457:118;;;4515:49;4524:39;4559:3;4524:29;4545:2;:7;;;4524:20;:29::i;4515:49::-;4508:56;;4457:118;4610:13;;;;4592:32;;4610:13;4592:11;;;;-1:-1:-1;;;4610:13:8;;;;-1:-1:-1;;;4604:19:8;4592:11;:32::i;:::-;4585:39;;4643:43;4672:2;:7;;;4681:4;4643:28;:43::i;:::-;4635:51;;4729:7;-1:-1:-1;;;;;4702:57:8;4720:7;-1:-1:-1;;;;;4702:57:8;4708:10;-1:-1:-1;;;;;4702:57:8;;4738:5;4745:13;4702:57;;;;;;;;;;;;;;;;;;;;;;;;2925:1841;;;;;;;;;;;;;;:::o;2075:844::-;2246:13;2272:29;;:::i;:::-;2303;;:::i;:::-;2336:43;2355:5;2362:7;2371;2336:18;:43::i;:::-;2271:108;;;;2403:2;:5;;;2394:14;;:2;:5;;;:14;;;2390:132;;;2456:7;;2498;;2429:93;;2456:7;2465:56;;2507:13;2465:32;:56::i;2390:132::-;2534:11;2547:13;2562;2577:22;2601;2639:63;2658:5;2665:2;:5;;;2639:63;;2672:2;:5;;;2639:63;;2679:13;2694:2;:7;;;2639:18;:63::i;:::-;2533:169;;;;;;;;;;2720:76;2745:5;2752:6;2760;2768;2776;2784:4;2790:2;:5;;;2720:76;;:24;:76::i;:::-;2832:13;;;;2713:83;;-1:-1:-1;2814:32:8;;2832:13;2814:11;;;;-1:-1:-1;;;2832:13:8;;;;-1:-1:-1;;;2826:19:8;2814:11;:32::i;:::-;2807:39;;2865:47;2892:2;:7;;;2901:10;:4;:8;;;:10::i;625:491::-;758:26;;:::i;:::-;786;;:::i;:::-;824:29;;:::i;:::-;-1:-1:-1;;;;;;856:22:8;;;;;;;:18;;;:22;;;;;;;;;824:54;;;;;;;;;;;;;;-1:-1:-1;;;824:54:8;;;;;;;;;;;;888:29;;:::i;:::-;-1:-1:-1;;;;;;920:22:8;;;;;;;:18;;;:22;;;;;;;;;888:54;;;;;;;;;;;;;;-1:-1:-1;;;888:54:8;;;;;;;;961:7;;888:54;;961:21;953:60;;;;;-1:-1:-1;;;953:60:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;1031:7;;-1:-1:-1;;;;;1031:21:8;1023:60;;;;;-1:-1:-1;;;1023:60:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;1102:2;;;;-1:-1:-1;625:491:8;-1:-1:-1;;;;625:491:8:o;2066:165:2:-;2148:11;2191:6;-1:-1:-1;;;;;2178:40:2;;2219:4;2178:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2178:46:2;;2066:165;-1:-1:-1;;;2066:165:2:o;1593:159::-;1668:15;1718:6;-1:-1:-1;;;;;1705:34:2;;1740:4;1705:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1457:130;1513:15;1563:6;-1:-1:-1;;;;;1550:28:2;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1550:30:2;;1457:130;-1:-1:-1;;1457:130:2:o;2188:459:6:-;2246:7;2487:6;2483:45;;-1:-1:-1;2516:1:6;2509:8;;2483:45;2550:5;;;2554:1;2550;:5;:1;2573:5;;;;;:10;2565:56;;;;-1:-1:-1;;;2565:56:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2639:1;-1:-1:-1;2188:459:6;;;;;:::o;3109:130::-;3167:7;3193:39;3197:1;3200;3193:39;;;;;;;;;;;;;;;;;:3;:39::i;10143:1200:8:-;10538:12;;;:19;10372:11;;;;;;10451:15;;;;;10538:19;10592:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10592:21:8;;10567:46;;10623:22;10661:7;10648:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10648:21:8;;10623:46;;10685:9;10680:493;10704:7;10700:1;:11;10680:493;;;10741:8;10736:1;:13;10732:364;;10775:55;10809:5;:12;;10822:1;10809:15;;;;;;;;;;;;;;;;;:20;-1:-1:-1;;;;;10809:20:8;10775:33;:55::i;:::-;10763:6;10770:1;10763:9;;;;;;;;;;;;;:67;;;;;;;;;;10751:6;10758:1;10751:9;;;;;;;;;;;;;:79;;;;;;;;;;;10732:364;;;10867:11;10911:56;10954:6;10962:4;10911:42;:56::i;:::-;10896:71;;-1:-1:-1;10896:71:8;-1:-1:-1;10992:10:8;:8;;;;;:10::i;:::-;10985:17;;11033:4;11021:6;11028:1;11021:9;;;;;;;;:16;;;;;;:9;;;;;;;;;:16;11067:14;;:8;;;11076:4;11067:8;:14::i;:::-;11055:6;11062:1;11055:9;;;;;;;;;;;;;:26;;;;;;;;;;;10732:364;;11120:6;11127:1;11120:9;;;;;;;;;;;;;;11110:19;;;;11153:6;11160:1;11153:9;;;;;;;;;;;;;;11143:19;;;;10713:3;;;;;;;10680:493;;;-1:-1:-1;11192:16:8;:10;;;;11203:4;11192:10;:16::i;:::-;11183:25;;11238:42;11256:6;11263:9;11256:17;;;;;;;;;;;;;;11275:4;11238:17;:42::i;:::-;11218:6;11225:9;11218:17;;;;;;;;:62;;;;;;;:17;;;;;;;;;;;:62;11321:6;;-1:-1:-1;11329:6:8;-1:-1:-1;;10143:1200:8;;;;;;;;;;;:::o;2931:1436:3:-;3267:12;;;;3316:13;;;3289:40;;;;;;;;;;;;;;;;;;;3187:17;3229:10;;;;3267:12;;;3289:24;;:40;;3316:13;;3289:40;;;3316:13;3289:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3340:13;3356:45;3369:6;3377;3385:5;3392:8;3356:12;:45::i;:::-;3340:61;-1:-1:-1;3411:11:3;;3433:878;3457:2;3453:1;:6;3433:878;;;3487:45;3500:6;3508;3516:5;3523:8;3487:12;:45::i;:::-;3480:52;-1:-1:-1;3609:10:3;3650:13;;;;;;;;;:88;;3711:26;:11;;;;3723:13;;;3711:11;:26::i;:::-;3699:9;:38;3697:41;;3650:88;;;3689:4;3680:6;3668:9;:18;:25;3666:28;;3650:88;3637:101;;3805:4;3792:10;:17;;;;;;;;3771:38;;3784:4;3771:10;:17;;;;;;;;:38;;;3767:534;;;3859:10;3847:9;3838:6;:18;:31;3829:40;;3934:10;3911:6;3918:12;3911:20;;;;;;;;;;;;;;:33;3888:6;3895:12;3888:20;;;;;;;;;;;;;:56;;;;;;;;;;;3963:61;3976:5;3983:6;3991;3999;4007;4015:8;3963:12;:61::i;:::-;4043:50;4064:6;4072;4080;4088:4;4043:20;:50::i;:::-;4112:17;;;;;;;;3767:534;4198:10;4186:9;4177:6;:18;:31;4168:40;;4250:36;4275:10;4250:6;4257:12;4250:20;;;;;;;;;;;;;;:24;;;;:36;;;;:::i;:::-;4227:6;4234:12;4227:20;;;;;;;;;;;;;:59;;;;;;;;;;;-1:-1:-1;3461:3:3;;3433:878;;;-1:-1:-1;4321:39:3;;;-1:-1:-1;;;4321:39:3;;;;;;;;;;;;;;;;;;;;;;;;;;;2931:1436;;;;;;;;;;:::o;8214:203:0:-;8274:6;8297;8288:16;;;;;;8310:14;8327:12;8334:1;8337;8327:5;:12::i;:::-;8310:29;-1:-1:-1;;;;;;;;;;;8354:29:0;;;;8345:39;;;;;4166:197;4223:6;4253:13;:9;;;:13;;;;;4270:2;4253:19;-1:-1:-1;;;;;;4287:19:0;;;;;:42;;-1:-1:-1;;;;;;4310:19:0;;;4287:42;4278:52;;;;;290:142:9;380:13;:9;;;:13;;;397:2;380:19;;290:142::o;2942:235:2:-;3052:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3052:56:2;-1:-1:-1;;;3052:56:2;;;3009:11;;3137:22;3146:6;3052:56;3137:8;:22::i;:::-;3126:44;;;;;;;;;;;;;;;-1:-1:-1;3126:44:2;;2942:235;-1:-1:-1;;;;2942:235:2:o;4929:304::-;5045:12;5069:17;-1:-1:-1;;;5146:4:2;5152:10;:8;;;;;:10::i;:::-;5089:74;;;;;;-1:-1:-1;;;;;5089:74:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;5089:74:2;;;;;;;-1:-1:-1;;;;;5089:74:2;;;;;;;;;;;5069:94;;5192:22;5201:6;5209:4;5192:8;:22::i;:::-;5181:45;;;;;;;;;;;;;;;-1:-1:-1;5181:45:2;;4929:304;-1:-1:-1;;;;;4929:304:2:o;6510:1205:8:-;6891:12;;;:19;6725:11;;;;;;6804:15;;;;;6891:19;6946:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6946:21:8;;6921:46;;6977:22;7015:7;7002:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7002:21:8;;6977:46;;7033:38;7074:5;:12;;7033:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;7033:53:8;;;;-1:-1:-1;;;7033:53:8;;;;;;;;;;;;;;;;;;;;;;;;;7102:9;7097:448;7121:7;7117:1;:11;7097:448;;;7158:8;7153:1;:13;7149:319;;7192:52;7226:9;7236:1;7226:12;;;;;;;;;;;;;;:17;;;7192:33;:52::i;:::-;7180:6;7187:1;7180:9;;;;;;;;;;;;;:64;;;;;;;;;;7168:6;7175:1;7168:9;;;;;;;;;;;;;:76;;;;;;;;;;;7149:319;;;7281:11;7325:49;7361:6;7369:4;7325:35;:49::i;:::-;7310:64;;-1:-1:-1;7310:64:8;-1:-1:-1;7405:14:8;:8;;;;7310:64;7405:8;:14::i;:::-;7393:6;7400:1;7393:9;;;;;;;;;;;;;:26;;;;;;;;;;;7449:4;7437:6;7444:1;7437:9;;;;;;;;;;;;;:16;;;;;;;;;;;7149:319;;7492:6;7499:1;7492:9;;;;;;;;;;;;;;7482:19;;;;7525:6;7532:1;7525:9;;;;;;;;;;;;;;7515:19;;;;7130:3;;;;;;;7097:448;;;-1:-1:-1;7564:16:8;:10;;;;7575:4;7564:10;:16::i;:::-;7555:25;;7610:42;7628:6;7635:9;7628:17;;;;;;;;;;;;;;7647:4;7610:17;:42::i;:::-;7590:6;7597:9;7590:17;;;;;;;;:62;;;;;;;:17;;;;;;;;;;;:62;-1:-1:-1;7693:6:8;;-1:-1:-1;7701:6:8;-1:-1:-1;;6510:1205:8;;;;;;;;;;;:::o;4236:313:2:-;4390:62;;;-1:-1:-1;;;;;4390:62:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;4390:62:2;-1:-1:-1;;;4390:62:2;;;4347:11;;4481:22;4490:6;4390:62;4481:8;:22::i;:::-;4470:44;;;;;;;;;;;;;;;-1:-1:-1;4470:44:2;;-1:-1:-1;4532:10:2;:8;;;;;:10::i;3479:248::-;3595:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3595:62:2;-1:-1:-1;;;3595:62:2;;;3551:12;;3686:22;3695:6;3595:62;3686:8;:22::i;7721:1245:8:-;8130:12;;;:19;7964:11;;;;;;8043:15;;;;;8130:19;8185:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8185:21:8;;8160:46;;8216:22;8254:7;8241:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8241:21:8;;8216:46;;8272:38;8313:5;:12;;8272:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;8272:53:8;;;;-1:-1:-1;;;8272:53:8;;;;;;;;;;;;;;;;;;;;;;;;;8341:9;8336:460;8360:7;8356:1;:11;8336:460;;;8397:8;8392:1;:13;8388:331;;8431:52;8465:9;8475:1;8465:12;;;;;;;8431:52;8419:6;8426:1;8419:9;;;;;;;;;;;;;:64;;;;;;;;;;8407:6;8414:1;8407:9;;;;;;;;;;;;;:76;;;;;;;;;;;8388:331;;;8520:11;8564:61;8600:6;8608:10;8620:4;8564:35;:61::i;:::-;8549:76;;-1:-1:-1;8549:76:8;-1:-1:-1;8656:14:8;:8;;;;8549:76;8656:8;:14::i;:::-;8644:6;8651:1;8644:9;;;;;;;;;;;;;:26;;;;;;;;;;;8700:4;8688:6;8695:1;8688:9;;;;;;;;;;;;;:16;;;;;;;;;;;8388:331;;8743:6;8750:1;8743:9;;;;;;;;;;;;;;8733:19;;;;8776:6;8783:1;8776:9;;;;;;;;;;;;;;8766:19;;;;8369:3;;;;;;;8336:460;;;-1:-1:-1;8815:16:8;:10;;;;8826:4;8815:10;:16::i;:::-;8806:25;;8861:42;8879:6;8886:9;8879:17;;;;;;;8861:42;8841:6;8848:9;8841:17;;;;;;;;:62;;;;;;;:17;;;;;;;;;;;:62;-1:-1:-1;8944:6:8;;-1:-1:-1;8952:6:8;-1:-1:-1;;7721:1245:8;;;;;;;;;;;;:::o;8972:1165::-;9367:12;;;:19;9201:11;;;;;;9280:15;;;;;9367:19;9421:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9421:21:8;;9396:46;;9452:22;9490:7;9477:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9477:21:8;;9452:46;;9514:9;9509:458;9533:7;9529:1;:11;9509:458;;;9570:8;9565:1;:13;9561:329;;9604:55;9638:5;:12;;9651:1;9638:15;;;;;;;9604:55;9592:6;9599:1;9592:9;;;;;;;;;;;;;:67;;;;;;;;;;9580:6;9587:1;9580:9;;;;;;;;;;;;;:79;;;;;;;;;;;9561:329;;;9696:11;9740:56;9783:6;9791:4;9740:42;:56::i;:::-;9725:71;;;;;;;;9827:4;9815:6;9822:1;9815:9;;;;;;;;:16;;;;;;:9;;;;;;;;;:16;9861:14;;:8;;;9870:4;9861:8;:14::i;:::-;9849:6;9856:1;9849:9;;;;;;;;;;;;;:26;;;;;;;;;;;9561:329;;9914:6;9921:1;9914:9;;;;;;;;;;;;;;9904:19;;;;9947:6;9954:1;9947:9;;;;;;;;;;;;;;9937:19;;;;9542:3;;;;;;;9509:458;;8843:117:0;8890:6;8913:14;;;;-1:-1:-1;;;;;;8913:14:0;;8904:24;;;;;;8945:1;8941;:5;;;:14;;8954:1;8941:14;;;-1:-1:-1;8949:2:0;;;8843:117::o;3721:272:6:-;3807:7;3841:12;3834:5;3826:28;;;;-1:-1:-1;;;3826:28:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3864:9;3880:1;3876;:5;;;;;;;3721:272;-1:-1:-1;;;;;3721:272:6:o;2492:162:2:-;2561:11;2604:6;-1:-1:-1;;;;;2591:41:2;;2641:4;2591:56;;;;;;;;;;;;;-1:-1:-1;;;;;2591:56:2;;;;;;;;;;;;;;;;;;;;;;;;;;2237:249;2408:71;;;-1:-1:-1;;;2408:71:2;;2467:4;2408:71;;;;;;;;;;;;2353:11;;;;-1:-1:-1;;;;;2408:50:2;;;;;:71;;;;;;;;;;;;;:50;:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2408:71:2;;;;;;;;;;;-1:-1:-1;2237:249:2;-1:-1:-1;;;2237:249:2:o;8577:105:0:-;8624:6;8647:14;;;;-1:-1:-1;;;;;;8647:14:0;;8638:24;;;;;3344:191;3401:6;3431:13;:9;;;:13;;;;;-1:-1:-1;;;;;;3459:19:0;;;;;:42;;-1:-1:-1;;;;;;3482:19:0;;;3450:52;;;;;3748:191;3805:6;3835:13;;;;:9;;;;:13;-1:-1:-1;;;;;;3863:19:0;;;;;:42;;-1:-1:-1;;;;;;3886:19:0;;;3854:52;;;;;1213:336:3;1426:10;;1462:11;;;;1388;;-1:-1:-1;;;1426:10:3;;;;;;;1462:11;;1491:51;1504:5;1511;1426:10;1462:11;1533:8;1491:12;:51::i;6774:1362::-;7024:13;;7063:11;;;;7006:15;7085:1045;7109:7;7105:1;:11;7085:1045;;;7137:14;7154:23;7165:8;7174:1;7165:11;;;;;;;;;;;;;;7154:6;:10;;;;:23;;;;:::i;:::-;7137:40;;7208:7;7196:19;;:6;7203:1;7196:9;;;;;;;;;;;;;;:19;;;7192:928;;;-1:-1:-1;;;7256:12:3;;7235:18;7303:24;:11;;;;7256:12;7303:11;:24::i;:::-;7287:40;;7362:6;7350:18;;:6;7357:1;7350:9;;;;;;;;;;;;;;:18;;;7346:287;;;7392:13;7408:40;7436:11;7408:23;7419:8;7428:1;7419:11;;;;;;;;;;;;;;7408:6;:10;;;;:23;;;;:::i;:::-;:27;;;;:40::i;:::-;7392:56;;7487:6;7475:18;;:6;7482:1;7475:9;;;;;;;;;;;;;;:18;;;7471:50;;;7495:26;;;-1:-1:-1;;;7495:26:3;;;;;;;;;;;;-1:-1:-1;;;7495:26:3;;;;;;;;;;;;;;7471:50;7580:6;7568;7575:1;7568:9;;;;;;;;;;;;;;:18;7547:39;;7559:6;7547;7554:1;7547:9;;;;;;;;;;;;;;:18;:39;;;7543:71;;;7588:26;;;-1:-1:-1;;;7588:26:3;;;;;;;;;;;;-1:-1:-1;;;7588:26:3;;;;;;;;;;;;;;7543:71;7346:287;;7192:928;;;;;-1:-1:-1;;;7692:12:3;;;7671:18;7739:24;:11;;;;7692:12;7739:11;:24::i;:::-;7723:40;;7798:6;7786:18;;:6;7793:1;7786:9;;;;;;;;;;;;;;:18;;;7782:324;;;7828:13;7844:23;7855:8;7864:1;7855:11;;;;;;;;;;;;;;7844:6;:10;;;;:23;;;;:::i;:::-;7828:39;-1:-1:-1;7898:23:3;:10;;;;7909:11;7898:10;:23::i;:::-;7889:32;;7960:6;7948:18;;:6;7955:1;7948:9;;;;;;;;;;;;;;:18;;;7944:50;;;7968:26;;;-1:-1:-1;;;7968:26:3;;;;;;;;;;;;-1:-1:-1;;;7968:26:3;;;;;;;;;;;;;;7944:50;8050:6;8057:1;8050:9;;;;;;;;;;;;;;8041:6;:18;8020:39;;8029:6;8036:1;8029:9;;;;;;;;;;;;;;8020:6;:18;:39;;;8016:71;;;8061:26;;;-1:-1:-1;;;8061:26:3;;;;;;;;;;;;-1:-1:-1;;;8061:26:3;;;;;;;;;;;;;;8016:71;7782:324;;7192:928;;;-1:-1:-1;7118:3:3;;7085:1045;;;;6774:1362;;;;;;;;:::o;5803:364::-;5971:13;;;6014:15;;;6055:21;;;6095:9;;;;5952:16;6095:9;;:30;;-1:-1:-1;;;6108:17:3;;;;;;6095:30;6087:73;;;;;-1:-1:-1;;;6087:73:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;5803:364;;;;;;;:::o;20427:1218:0:-;20487:7;20511:6;20502:16;;;;;;20525:14;-1:-1:-1;;;;;20550:1:0;:55;20546:1005;;20634:1;20628:2;20623:1;:7;;20622:13;;;;;;20613:22;;20546:1005;;;20668:3;20692:8;;;20718:11;20712:17;;20708:48;;20740:2;20744:9;;;;20733;20708:48;20773:7;20767:2;:13;20763:44;;20791:2;20795:9;;;;20784;20763:44;20824:5;20818:2;:11;20814:40;;20840:1;20843:8;;;;20833;20814:40;20871:4;20865:2;:10;20861:39;;20886:1;20889:8;;;;20879;20861:39;20917:3;20911:2;:9;20907:38;;20931:1;20934:8;;;;20924;20907:38;20962:3;20956:2;:9;20952:23;;20974:1;20967:8;;;;20952:23;21061:3;21055;:9;21050:1;21046;:5;:18;;21068:1;21045:24;21037:3;21031;:9;21026:1;:14;;21025:45;;;;;;21016:54;;-1:-1:-1;;;;;21087:6:0;:44;;21078:54;;;;;;21169:3;21164:8;;;21154:19;;-1:-1:-1;;;;;21204:38:0;;21194:49;;21270:3;21265:8;;;21299:2;21294:7;;;21314;;;21310:20;;;21329:1;21323:7;;;;21310:20;21402:3;21396:9;;;;21338:8;;21417:7;;;21413:20;;;21432:1;21426:7;;;;21413:20;21441:8;;;21515:3;21509:9;;;21503:15;;21495:24;;;;21543:1;21538:2;:6;;;;;;21528:16;;;;20546:1005;;;;;;;-1:-1:-1;;;;;21566:6:0;:44;;21557:54;;;;;950:501:2;1023:12;1055:20;:7;-1:-1:-1;;;;;1055:18:2;;:20::i;:::-;1047:70;;;;-1:-1:-1;;;1047:70:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1166:13;1181:24;1209:7;-1:-1:-1;;;;;1209:20:2;1230:5;1209:27;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1209:27:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1165:71;;;;1323:1;1313:8;1310:15;1307:2;;;1375:16;1368:4;1355:11;1351:22;1344:48;3183:290;3319:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3319:69:2;-1:-1:-1;;;3319:69:2;;;3263:11;;;;3425:22;3434:6;3319:69;3425:8;:22::i;:::-;3414:52;;;;;;;;;;;;;;;-1:-1:-1;3414:52:2;;;;;;;;;;;-1:-1:-1;3183:290:2;-1:-1:-1;;;;3183:290:2:o;4555:368::-;4735:75;;;-1:-1:-1;;;;;4735:75:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;4735:75:2;-1:-1:-1;;;4735:75:2;;;4679:11;;;;4847:22;4856:6;4735:75;4847:8;:22::i;:::-;4836:52;;;;;;;;;;;;;;;-1:-1:-1;4836:52:2;;;;;;;;;-1:-1:-1;4836:52:2;-1:-1:-1;4906:10:2;:8;;;;;:10::i;:::-;4899:17;;4555:368;;;;;;;:::o;1555:426:3:-;1779:12;;1738:11;;;1802:173;1826:7;1822:1;:11;1802:173;;;1854:13;1870:22;1880:8;1889:1;1880:11;;;;;;;;;;;;;;1870:5;:9;;;;:22;;;;:::i;:::-;1854:38;;1914:50;1932:5;1938:1;1932:8;;;;;;;;;;;;;;1942:6;1950:5;1957:6;1914:17;:50::i;:::-;1906:58;;;;-1:-1:-1;1835:3:3;;1802:173;;;;1555:426;;;;;;;;:::o;726:413:1:-;1086:20;1124:8;;;726:413::o;1987:938:3:-;2131:11;2165:6;2158:13;;:4;:13;;;2154:765;;;2187:17;2207:23;:10;;;;-1:-1:-1;;;2218:11:3;;;2207:10;:23::i;:::-;2187:43;;2256:10;2249:17;;:4;:17;;;2245:287;;;2306:17;;;2349:22;:14;;;;2364:6;2349:14;:22::i;:::-;2342:29;-1:-1:-1;2396:16:3;:8;;;;2405:6;2396:8;:16::i;:::-;2389:23;-1:-1:-1;;;;2435:10:3;;;;;2431:26;;;-1:-1:-1;;;2447:10:3;;2431:26;2483:20;:8;;;;2492:10;2483:8;:20::i;:::-;2476:27;;2245:287;;;;2531:1;2524:8;;2245:287;2154:765;;;;2563:17;2583:23;:10;;;;-1:-1:-1;;;2594:11:3;;2583:10;:23::i;:::-;2563:43;;2632:10;2625:17;;:4;:17;;;2621:287;;;2682:17;;;2725:22;:14;;;;2740:6;2725:14;:22::i;:::-;2718:29;-1:-1:-1;2772:16:3;:8;;;;2781:6;2772:8;:16::i;:::-;2765:23;-1:-1:-1;;;;2811:10:3;;;;;2807:26;;;-1:-1:-1;;;2823:10:3;;2807:26;2859:20;:8;;;;2868:10;2859:8;:20::i;:::-;2852:27;;2621:287;;;;2907:1;2900:8;;2621:287;2154:765;1987:938;;;;;;:::o;6651:222:0:-;6708:6;6731:1;:6;;6736:1;6731:6;;6722:16;;;;;;6744:13;6781:1;6760:22;;6775:2;6769:1;6761:10;;:16;;6760:22;;;;;;;-1:-1:-1;;;;;;;6797:19:0;;;;;:42;;-1:-1:-1;;;;;;6820:19:0;;;6788:52;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;:::o
Swarm Source
ipfs://66ab6675d9d0ae62d37d2fc77135afce24e2ce55a5af45333cb16a6dc968037b
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.