Contract
0x6be9b5dcb835478e68a6c06a66eea1c0c16e74bb
3
Contract Overview
Balance:
0 ETH
ETH Value:
$0.00
My Name Tag:
Not Available
Txn Hash | Method |
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0xc727087b184cde0e47115d1477b53b044fef26c94043054ae36c75e2843865d0 | Initialize | 9626395 | 297 days 12 hrs ago | 0x21bc9179d5c529b52e3ee8f6ecf0e63fa231d16c | IN | 0x6be9b5dcb835478e68a6c06a66eea1c0c16e74bb | 0 ETH | 0.000254282251 ETH | |
0x7853906ced15ca6ae9502ed7b3d4483fde0cd9b4e62d8eea8e81a0a74993b029 | 0x60806040 | 9626379 | 297 days 12 hrs ago | 0x21bc9179d5c529b52e3ee8f6ecf0e63fa231d16c | IN | Create: InitialConvertibleOfferingMarket | 0 ETH | 0.029391656315 ETH |
[ Download CSV Export ]
Latest 23 internal transactions
[ Download CSV Export ]
Contract Name:
InitialConvertibleOfferingMarket
Compiler Version
v0.7.6+commit.7338295f
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; import "@solv/v2-solidity-utils/contracts/misc/Constants.sol"; import "@solv/v2-solidity-utils/contracts/access/AdminControl.sol"; import "@solv/v2-solidity-utils/contracts/openzeppelin/math/SafeMathUpgradeable.sol"; import "@solv/v2-solidity-utils/contracts/openzeppelin/utils/EnumerableSetUpgradeable.sol"; import "@solv/v2-solidity-utils/contracts/math/SafeMathUpgradeable128.sol"; import "@solv/v2-solidity-utils/contracts/helpers/VNFTTransferHelper.sol"; import "@solv/v2-solidity-utils/contracts/helpers/ERC20TransferHelper.sol"; import "@solv/v2-solidity-utils/contracts/openzeppelin/utils/ReentrancyGuardUpgradeable.sol"; import "@solv/v2-solver/contracts/interface/ISolver.sol"; import "./PriceManager.sol"; abstract contract OfferingMarketCore is PriceManager, AdminControl, ReentrancyGuardUpgradeable { using SafeMathUpgradeable for uint256; using SafeMathUpgradeable128 for uint128; using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet; using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet; event AddMarket( address indexed voucher, Constants.VoucherType voucherType, address asset, uint8 decimals, uint16 feeRate, bool onlyManangerOffer ); event RemoveMarket(address indexed voucher); event Offer( address indexed voucher, address indexed issuer, Offering offering ); event Remove( address indexed issuer, uint24 indexed offeringId, address voucher, uint128 total, uint128 sold ); event FixedPriceSet( address indexed voucher, uint24 indexed offeringId, uint8 priceType, uint128 lastPrice ); event DecliningPriceSet( address indexed voucher, uint24 indexed offeringId, uint128 highest, uint128 lowest, uint32 duration, uint32 interval ); event Traded( address indexed buyer, uint24 indexed offeringId, address indexed voucher, uint256 voucherId, uint24 tradeId, uint32 tradeTime, address currency, uint8 priceType, uint128 price, uint128 tradedUnits, uint256 tradedAmount, uint128 fee ); event SetCurrency(address indexed currency, bool enable); event WithdrawFee(address voucher, uint256 reduceAmount); event NewSolver(ISolver oldSolver, ISolver newSolver); struct Market { Constants.VoucherType voucherType; address voucherPool; address asset; uint8 decimals; uint16 feeRate; bool onlyManangerOffer; bool isValid; } struct Offering { uint24 offeringId; uint32 startTime; uint32 endTime; PriceManager.PriceType priceType; uint128 totalUnits; uint128 units; uint128 min; uint128 max; address voucher; address currency; address issuer; bool useAllowList; bool isValid; } //key: offeringId mapping(uint24 => Offering) public offerings; //key: voucher mapping(address => Market) public markets; EnumerableSetUpgradeable.AddressSet internal _currencies; EnumerableSetUpgradeable.AddressSet internal _vouchers; //voucher => offeringId mapping(address => EnumerableSetUpgradeable.UintSet) internal _voucherOfferings; mapping(address => EnumerableSetUpgradeable.AddressSet) internal _allowAddresses; // managers with authorities to set allow addresses of a voucher market and offer offering mapping(address => EnumerableSetUpgradeable.AddressSet) internal _voucherManagers; // records of user purchased units from an order mapping(uint24 => mapping(address => uint128)) internal _tradeRecords; ISolver public solver; uint24 public nextOfferingId; uint24 public nextTradeId; modifier onlyVoucherManager(address voucher_) { require( msg.sender == admin || _voucherManagers[voucher_].contains(msg.sender), "only manager" ); _; } function _mintVoucher(uint24 oferingId, uint128 units) internal virtual returns (uint256 voucherId); function _refund(uint24 offeringId, uint128 units) internal virtual; function isSupportVoucherType(Constants.VoucherType voucherType) public virtual returns (bool); function initialize(ISolver solver_) external initializer { ReentrancyGuardUpgradeable.__ReentrancyGuard_init(); AdminControl.__AdminControl_init(msg.sender); nextOfferingId = 1; nextTradeId = 1; setSolver(solver_); } function _offer( address voucher_, address currency_, uint128 units_, uint128 min_, uint128 max_, uint32 startTime_, uint32 endTime_, bool useAllowList_, PriceManager.PriceType priceType_, bytes memory priceData_ ) internal nonReentrant returns (uint24 offeringId) { require( voucher_ != address(0) && currency_ != address(0), "address cannot be 0" ); Market memory market = markets[voucher_]; require(market.isValid, "unsupported voucher"); require(_currencies.contains(currency_), "unsupported currency"); require(endTime_ > startTime_, "endTime less than startTime"); if (market.onlyManangerOffer) { require( _voucherManagers[voucher_].contains(msg.sender), "only manager" ); } if (max_ > 0) { require(min_ <= max_, "min > max"); } uint256 err = solver.operationAllowed( "Offer", abi.encode( voucher_, msg.sender, currency_, units_, min_, max_, startTime_, endTime_, useAllowList_, priceType_, priceData_ ) ); require(err == 0, "solver not allowed"); offeringId = _generateNextofferingId(); offerings[offeringId] = Offering({ offeringId: offeringId, startTime: startTime_, endTime: endTime_, priceType: priceType_, totalUnits: units_, units: units_, min: min_, max: max_, currency: currency_, issuer: msg.sender, voucher: voucher_, useAllowList: useAllowList_, isValid: true }); Offering memory offering = offerings[offeringId]; _setPrice(offering, priceType_, priceData_); solver.operationVerify( "Offer", abi.encode(offering.voucher, offering.offeringId) ); emit Offer(offering.voucher, offering.issuer, offering); return offeringId; } function _setPrice( Offering memory offering_, PriceManager.PriceType priceType_, bytes memory priceData_ ) internal { if (priceType_ == PriceManager.PriceType.FIXED) { uint128 price = abi.decode(priceData_, (uint128)); PriceManager.setFixedPrice(offering_.offeringId, price); emit FixedPriceSet( offering_.voucher, offering_.offeringId, uint8(priceType_), price ); } else { ( uint128 highest, uint128 lowest, uint32 duration, uint32 interval ) = abi.decode(priceData_, (uint128, uint128, uint32, uint32)); PriceManager.setDecliningPrice( offering_.offeringId, offering_.startTime, highest, lowest, duration, interval ); emit DecliningPriceSet( offering_.voucher, offering_.offeringId, highest, lowest, duration, interval ); } } function buy(uint24 offeringId_, uint128 units_) external payable virtual nonReentrant returns (uint256 amount_, uint128 fee_) { address buyer = msg.sender; uint128 price = getPrice(offeringId_); Offering storage offering = offerings[offeringId_]; require(offering.isValid, "invalid offering"); Market memory market = markets[offering.voucher]; require(market.isValid, "invalid market"); amount_ = uint256(units_).mul(uint256(price)).div( uint256(10**market.decimals) ); fee_ = _getFee(offering.voucher, amount_); uint256 err = solver.operationAllowed( "Buy", abi.encode( offering.voucher, offeringId_, buyer, amount_, units_, price ) ); require(err == 0, "Solver: not allowed"); BuyParameter memory buyParameter = BuyParameter({ buyer: buyer, amount: amount_, units: units_, price: price, fee: fee_ }); _buy(offering, buyParameter); return (amount_, fee_); } struct BuyLocalVar { uint256 transferInAmount; uint256 transferOutAmount; } struct BuyParameter { address buyer; uint256 amount; uint128 units; uint128 price; uint128 fee; } function _buy(Offering storage offering_, BuyParameter memory parameter_) internal { require(offering_.isValid, "offering invalid"); require(offering_.units > 0, "sold out"); require( block.timestamp >= offering_.startTime && block.timestamp <= offering_.endTime, "not offering time" ); if (offering_.useAllowList) { require( _allowAddresses[offering_.voucher].contains(parameter_.buyer), "not in allow list" ); } if (offering_.units >= offering_.min) { require(parameter_.units >= offering_.min, "min amount not met"); } if (offering_.max > 0) { uint128 purchased = _tradeRecords[offering_.offeringId][ parameter_.buyer ].add(parameter_.units); require(purchased <= offering_.max, "exceeds purchase limit"); _tradeRecords[offering_.offeringId][parameter_.buyer] = purchased; } offering_.units = offering_.units.sub( parameter_.units, "insufficient units for sale" ); BuyLocalVar memory vars; vars.transferInAmount = parameter_.amount; vars.transferOutAmount = parameter_.amount.sub( parameter_.fee, "fee exceeds amount" ); uint256 voucherId = _transferAsset( offering_, parameter_.buyer, vars.transferInAmount, parameter_.units, vars.transferOutAmount ); solver.operationVerify( "Buy", abi.encode( offering_.offeringId, parameter_.buyer, parameter_.amount, parameter_.units, parameter_.fee ) ); emit Traded( parameter_.buyer, offering_.offeringId, offering_.voucher, voucherId, _generateNextTradeId(), uint32(block.timestamp), offering_.currency, uint8(offering_.priceType), parameter_.price, parameter_.units, parameter_.amount, parameter_.fee ); } function _transferAsset( Offering memory offering_, address buyer_, uint256 transferInAmount_, uint128 transferOutUnits_, uint256 transferOutAmount_ ) internal returns (uint256 voucherId) { ERC20TransferHelper.doTransferIn( offering_.currency, buyer_, transferInAmount_ ); voucherId = _mintVoucher(offering_.offeringId, transferOutUnits_); VNFTTransferHelper.doTransferOut(offering_.voucher, buyer_, voucherId); ERC20TransferHelper.doTransferOut( offering_.currency, payable(offering_.issuer), transferOutAmount_ ); } function purchasedUnits(uint24 offeringId_, address buyer_) external view returns (uint128) { return _tradeRecords[offeringId_][buyer_]; } function remove(uint24 offeringId_) external virtual nonReentrant { Offering memory offering = offerings[offeringId_]; require(offering.isValid, "invalid offering"); require(offering.issuer == msg.sender, "only issuer"); require( block.timestamp < offering.startTime || block.timestamp > offering.endTime, "offering processing" ); uint256 err = solver.operationAllowed( "Remove", abi.encode(offering.voucher, offering.offeringId, offering.issuer) ); require(err == 0, "Solver: not allowed"); _refund(offeringId_, offering.units); emit Remove( offering.issuer, offering.offeringId, offering.voucher, offering.totalUnits, offering.totalUnits - offering.units ); delete offerings[offeringId_]; } function _getFee(address voucher_, uint256 amount) internal view returns (uint128) { Market storage market = markets[voucher_]; uint256 fee = amount.mul(uint256(market.feeRate)).div( uint256(Constants.FULL_PERCENTAGE) ); require(fee <= uint128(-1), "Fee: exceeds uint128 max"); return uint128(fee); } function getPrice(uint24 offeringId_) public view virtual returns (uint128) { return PriceManager.price(offerings[offeringId_].priceType, offeringId_); } function totalOfferingsOfvoucher(address voucher_) external view virtual returns (uint256) { return _voucherOfferings[voucher_].length(); } function offeringIdOfvoucherByIndex(address voucher_, uint256 index_) external view virtual returns (uint256) { return _voucherOfferings[voucher_].at(index_); } function _generateNextofferingId() internal returns (uint24) { return nextOfferingId++; } function _generateNextTradeId() internal returns (uint24) { return nextTradeId++; } function addMarket( address voucher_, address voucherPool_, Constants.VoucherType voucherType_, address asset_, uint8 decimals_, uint16 feeRate_, bool onlyManangerOffer_ ) external onlyAdmin { if (_vouchers.contains(voucher_)) { revert("already added"); } require(isSupportVoucherType(voucherType_), "unsupported voucher type"); require(feeRate_ <= Constants.FULL_PERCENTAGE, "invalid fee rate"); markets[voucher_].voucherPool = voucherPool_; markets[voucher_].isValid = true; markets[voucher_].decimals = decimals_; markets[voucher_].feeRate = feeRate_; markets[voucher_].voucherType = voucherType_; markets[voucher_].asset = asset_; markets[voucher_].onlyManangerOffer = onlyManangerOffer_; _vouchers.add(voucher_); emit AddMarket( voucher_, voucherType_, asset_, decimals_, feeRate_, onlyManangerOffer_ ); } function removeMarket(address voucher_) external onlyAdmin { _vouchers.remove(voucher_); delete markets[voucher_]; emit RemoveMarket(voucher_); } function setCurrency(address currency_, bool enable_) external onlyAdmin { if (enable_) { _currencies.add(currency_); } else { _currencies.remove(currency_); } emit SetCurrency(currency_, enable_); } function withdrawFee(address currency_, uint256 reduceAmount_) external onlyAdmin { ERC20TransferHelper.doTransferOut( currency_, payable(admin), reduceAmount_ ); emit WithdrawFee(currency_, reduceAmount_); } function addAllowAddress( address voucher_, address[] calldata addresses_, bool resetExisting_ ) external onlyVoucherManager(voucher_) { require(markets[voucher_].isValid, "unsupported voucher"); EnumerableSetUpgradeable.AddressSet storage set = _allowAddresses[ voucher_ ]; if (resetExisting_) { while (set.length() != 0) { set.remove(set.at(0)); } } for (uint256 i = 0; i < addresses_.length; i++) { set.add(addresses_[i]); } } function removeAllowAddress(address voucher_, address[] calldata addresses_) external onlyVoucherManager(voucher_) { require(markets[voucher_].isValid, "unsupported voucher"); EnumerableSetUpgradeable.AddressSet storage set = _allowAddresses[ voucher_ ]; for (uint256 i = 0; i < addresses_.length; i++) { set.remove(addresses_[i]); } } function isBuyerAllowed(address voucher_, address buyer_) external view returns (bool) { return _allowAddresses[voucher_].contains(buyer_); } function setVoucherManager( address voucher_, address[] calldata managers_, bool resetExisting_ ) external onlyAdmin { require(markets[voucher_].isValid, "unsupported voucher"); EnumerableSetUpgradeable.AddressSet storage set = _voucherManagers[ voucher_ ]; if (resetExisting_) { while (set.length() != 0) { set.remove(set.at(0)); } } for (uint256 i = 0; i < managers_.length; i++) { set.add(managers_[i]); } } function voucherManagers(address voucher_) external view returns (address[] memory managers_) { managers_ = new address[](_voucherManagers[voucher_].length()); for (uint256 i = 0; i < _voucherManagers[voucher_].length(); i++) { managers_[i] = _voucherManagers[voucher_].at(i); } } function setSolver(ISolver newSolver_) public virtual onlyAdmin { ISolver oldSolver = solver; require(newSolver_.isSolver(), "invalid solver"); solver = newSolver_; emit NewSolver(oldSolver, newSolver_); } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; contract PriceManager { enum PriceType { FIXED, DECLIINING_BY_TIME } struct DecliningPrice { uint128 highest; //起始价格 uint128 lowest; //最终价格 uint32 startTime; uint32 duration; //持续时间 uint32 interval; //降价周期 } //saleId => DecliningPrice mapping(uint24 => DecliningPrice) internal decliningPrices; mapping(uint24 => uint128) internal fixedPrices; function price(PriceType priceType_, uint24 offeringId_) internal view returns (uint128) { if (priceType_ == PriceType.FIXED) { return fixedPrices[offeringId_]; } if (priceType_ == PriceType.DECLIINING_BY_TIME) { DecliningPrice storage price_ = decliningPrices[offeringId_]; if (block.timestamp >= price_.startTime + price_.duration) { return price_.lowest; } if (block.timestamp <= price_.startTime) { return price_.highest; } uint256 lastPrice = price_.highest - ((block.timestamp - price_.startTime) / price_.interval) * ((price_.interval * (price_.highest - price_.lowest)) / price_.duration); uint256 price256 = lastPrice < price_.lowest ? price_.lowest : lastPrice; require(price256 <= uint128(-1), "price: exceeds uint128 max"); return uint128(price256); } revert("unsupported priceType"); } function setFixedPrice(uint24 offeringId_, uint128 price_) internal { fixedPrices[offeringId_] = price_; } function setDecliningPrice( uint24 offeringId_, uint32 startTime_, uint128 highest_, uint128 lowest_, uint32 duration_, uint32 interval_ ) internal { require(highest_ > lowest_, "highest must greater than lowest"); require(duration_ >= interval_, "duration must greater than interval"); decliningPrices[offeringId_].startTime = startTime_; decliningPrices[offeringId_].highest = highest_; decliningPrices[offeringId_].lowest = lowest_; decliningPrices[offeringId_].duration = duration_; decliningPrices[offeringId_].interval = interval_; } function getDecliningPrice(uint24 offeringId_) external view returns ( uint128 highest, uint128 lowest, uint32 startTime, uint32 duration, uint32 interval ) { DecliningPrice storage decliningPrice = decliningPrices[offeringId_]; return ( decliningPrice.highest, decliningPrice.lowest, decliningPrice.startTime, decliningPrice.duration, decliningPrice.interval ); } function getFixedPrice(uint24 offeringId_) external view returns (uint128) { return fixedPrices[offeringId_]; } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "../openzeppelin/utils/ContextUpgradeable.sol"; import "../openzeppelin/proxy/Initializable.sol"; abstract contract AdminControl is Initializable, ContextUpgradeable { event NewAdmin(address oldAdmin, address newAdmin); event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin); address public admin; address public pendingAdmin; modifier onlyAdmin() { require(_msgSender() == admin, "only admin"); _; } function __AdminControl_init(address admin_) internal initializer { admin = admin_; } function setPendingAdmin(address newPendingAdmin_) external virtual onlyAdmin { emit NewPendingAdmin(pendingAdmin, newPendingAdmin_); pendingAdmin = newPendingAdmin_; } function acceptAdmin() external virtual { require(_msgSender() == pendingAdmin, "only pending admin"); emit NewAdmin(admin, pendingAdmin); admin = pendingAdmin; pendingAdmin = address(0); } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "../misc/Constants.sol"; interface ERC20Interface { function balanceOf(address account) external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); } // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false library ERC20TransferHelper { function doTransferIn( address underlying, address from, uint256 amount ) internal returns (uint256) { if (underlying == Constants.ETH_ADDRESS) { // Sanity checks require(tx.origin == from || msg.sender == from, "sender mismatch"); require(msg.value == amount, "value mismatch"); return amount; } else { require(msg.value == 0, "don't support msg.value"); uint256 balanceBefore = ERC20Interface(underlying).balanceOf( address(this) ); (bool success, bytes memory data) = underlying.call( abi.encodeWithSelector( ERC20Interface.transferFrom.selector, from, address(this), amount ) ); require( success && (data.length == 0 || abi.decode(data, (bool))), "STF" ); // Calculate the amount that was *actually* transferred uint256 balanceAfter = ERC20Interface(underlying).balanceOf( address(this) ); require( balanceAfter >= balanceBefore, "TOKEN_TRANSFER_IN_OVERFLOW" ); return balanceAfter - balanceBefore; // underflow already checked above, just subtract } } function doTransferOut( address underlying, address payable to, uint256 amount ) internal { if (underlying == Constants.ETH_ADDRESS) { (bool success, ) = to.call{value: amount}(new bytes(0)); require(success, "STE"); } else { (bool success, bytes memory data) = underlying.call( abi.encodeWithSelector( ERC20Interface.transfer.selector, to, amount ) ); require( success && (data.length == 0 || abi.decode(data, (bool))), "ST" ); } } function getCashPrior(address underlying_) internal view returns (uint256) { if (underlying_ == Constants.ETH_ADDRESS) { uint256 startingBalance = sub(address(this).balance, msg.value); return startingBalance; } else { ERC20Interface token = ERC20Interface(underlying_); return token.balanceOf(address(this)); } } function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; interface ERC721Interface { function transferFrom( address from, address to, uint256 tokenId ) external; } interface VNFTInterface { function transferFrom( address from, address to, uint256 tokenId, uint256 units ) external returns (uint256 newTokenId); function safeTransferFrom( address from, address to, uint256 tokenId, uint256 units, bytes calldata data ) external returns (uint256 newTokenId); function transferFrom( address from, address to, uint256 tokenId, uint256 targetTokenId, uint256 units ) external; function safeTransferFrom( address from, address to, uint256 tokenId, uint256 targetTokenId, uint256 units, bytes calldata data ) external; } library VNFTTransferHelper { function doTransferIn( address underlying, address from, uint256 tokenId ) internal { ERC721Interface token = ERC721Interface(underlying); token.transferFrom(from, address(this), tokenId); } function doTransferOut( address underlying, address to, uint256 tokenId ) internal { ERC721Interface token = ERC721Interface(underlying); token.transferFrom(address(this), to, tokenId); } function doTransferIn( address underlying, address from, uint256 tokenId, uint256 units ) internal { VNFTInterface token = VNFTInterface(underlying); token.safeTransferFrom(from, address(this), tokenId, units, ""); } function doTransferOut( address underlying, address to, uint256 tokenId, uint256 units ) internal returns (uint256 newTokenId) { VNFTInterface token = VNFTInterface(underlying); newTokenId = token.safeTransferFrom( address(this), to, tokenId, units, "" ); } function doTransferOut( address underlying, address to, uint256 tokenId, uint256 targetTokenId, uint256 units ) internal { VNFTInterface token = VNFTInterface(underlying); token.safeTransferFrom( address(this), to, tokenId, targetTokenId, units, "" ); } }
// 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 SafeMathUpgradeable128 { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint128 a, uint128 b) internal pure returns (bool, uint128) { uint128 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint128 a, uint128 b) internal pure returns (bool, uint128) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint128 a, uint128 b) internal pure returns (bool, 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 (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint128 a, uint128 b) internal pure returns (bool, uint128) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint128 a, uint128 b) internal pure returns (bool, uint128) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint128 a, uint128 b) internal pure returns (uint128) { uint128 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(uint128 a, uint128 b) internal pure returns (uint128) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint128 a, uint128 b) internal pure returns (uint128) { if (a == 0) return 0; uint128 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting 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(uint128 a, uint128 b) internal pure returns (uint128) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting 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(uint128 a, uint128 b) internal pure returns (uint128) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint128 a, uint128 b, string memory errorMessage) internal pure returns (uint128) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * 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(uint128 a, uint128 b, string memory errorMessage) internal pure returns (uint128) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * 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(uint128 a, uint128 b, string memory errorMessage) internal pure returns (uint128) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; library Constants { enum ClaimType { LINEAR, ONE_TIME, STAGED } enum VoucherType { STANDARD_VESTING, FLEXIBLE_DATE_VESTING, BOUNDING } uint32 internal constant FULL_PERCENTAGE = 10000; address internal constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; }
// 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 SafeMathUpgradeable { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, 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 (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @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) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @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) { 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, reverting 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) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting 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) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * 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); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * 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); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * 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 // solhint-disable-next-line compiler-version pragma solidity >=0.4.24 <0.8.0; import "../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {UpgradeableProxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require(_initializing || _isConstructor() || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /// @dev Returns true if and only if the function is running in the constructor function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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 pragma solidity >=0.6.0 <0.8.0; import "../proxy/Initializable.sol"; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer { } function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSetUpgradeable { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "../proxy/Initializable.sol"; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal initializer { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal initializer { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; interface ISolver { event SetOperationPaused ( address product, string operation, bool setPaused ); function isSolver() external pure returns (bool); function setOperationPaused(address product_, string calldata operation_, bool setPaused_) external; function operationAllowed(string calldata operation_, bytes calldata data_) external returns (uint256); function operationVerify(string calldata operation_, bytes calldata data_) external returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; import "@solv/v2-offering-market-core/contracts/OfferingMarketCore.sol"; interface IConvertibleVoucher { function mint( address issuer_, address fundCurrency_, uint128 lowestPrice_, uint128 highestPrice_, uint64 effectiveTime_, uint64 maturity_, uint256 tokenInAmount_ // 最大偿付token数量 (at lowestPrice) ) external returns (uint256 slot, uint256 tokenId); } interface IConvertiblePool { function validateSlotParams( address issuer_, address fundCurrency_, uint128 lowestPrice_, uint128 highestPrice_, uint64 effectiveTime_, uint64 maturity_, uint8 collateralType_ ) external view; } interface IERC20 { function approve(address spender, uint256 amount) external returns (bool); function balanceOf(address account) external view returns (uint256); } contract InitialConvertibleOfferingMarket is OfferingMarketCore { using SafeMathUpgradeable128 for uint128; struct MintParameter { uint128 lowestPrice; uint128 highestPrice; uint128 tokenInAmount; uint64 effectiveTime; uint64 maturity; } //key: offeringId mapping(uint24 => MintParameter) internal _mintParameters; function mintParameters(uint24 offeringId_) external view returns (MintParameter memory) { return _mintParameters[offeringId_]; } function offer( address voucher_, address currency_, uint128 min_, uint128 max_, uint32 startTime_, uint32 endTime_, bool useAllowList_, PriceManager.PriceType priceType_, bytes calldata priceData_, MintParameter calldata mintParameter_ ) external returns (uint24 offeringId) { Market memory market = markets[voucher_]; IConvertiblePool(market.voucherPool).validateSlotParams( msg.sender, currency_, mintParameter_.lowestPrice, mintParameter_.highestPrice, mintParameter_.effectiveTime, mintParameter_.maturity, 0 //ERC20 ); uint128 units = mintParameter_.tokenInAmount.mul( mintParameter_.lowestPrice ); ERC20TransferHelper.doTransferIn( market.asset, msg.sender, mintParameter_.tokenInAmount ); offeringId = OfferingMarketCore._offer( voucher_, currency_, units, min_, max_, startTime_, endTime_, useAllowList_, priceType_, priceData_ ); _mintParameters[offeringId] = mintParameter_; } function _mintVoucher(uint24 offeringId_, uint128 units_) internal virtual override returns (uint256 voucherId) { Offering memory offering = offerings[offeringId_]; MintParameter memory parameter = _mintParameters[offeringId_]; uint128 tokenInAmount = units_.div(parameter.lowestPrice); IERC20(markets[offering.voucher].asset).approve( markets[offering.voucher].voucherPool, tokenInAmount ); (, voucherId) = IConvertibleVoucher(offering.voucher).mint( offering.issuer, offering.currency, parameter.lowestPrice, parameter.highestPrice, parameter.effectiveTime, parameter.maturity, tokenInAmount ); } function _refund(uint24 offeringId_, uint128 units_) internal virtual override { Offering memory offering = offerings[offeringId_]; address asset = markets[offering.voucher].asset; uint256 balance = IERC20(asset).balanceOf(address(this)); uint256 refundAmount = units_.div( _mintParameters[offeringId_].lowestPrice ); if (refundAmount > balance) { refundAmount = balance; } ERC20TransferHelper.doTransferOut( markets[offering.voucher].asset, payable(offering.issuer), refundAmount ); } function isSupportVoucherType(Constants.VoucherType voucherType_) public pure override returns (bool) { return (voucherType_ == Constants.VoucherType.BOUNDING); } }
{ "evmVersion": "istanbul", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 1 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voucher","type":"address"},{"indexed":false,"internalType":"enum Constants.VoucherType","name":"voucherType","type":"uint8"},{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint8","name":"decimals","type":"uint8"},{"indexed":false,"internalType":"uint16","name":"feeRate","type":"uint16"},{"indexed":false,"internalType":"bool","name":"onlyManangerOffer","type":"bool"}],"name":"AddMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voucher","type":"address"},{"indexed":true,"internalType":"uint24","name":"offeringId","type":"uint24"},{"indexed":false,"internalType":"uint128","name":"highest","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"lowest","type":"uint128"},{"indexed":false,"internalType":"uint32","name":"duration","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"interval","type":"uint32"}],"name":"DecliningPriceSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voucher","type":"address"},{"indexed":true,"internalType":"uint24","name":"offeringId","type":"uint24"},{"indexed":false,"internalType":"uint8","name":"priceType","type":"uint8"},{"indexed":false,"internalType":"uint128","name":"lastPrice","type":"uint128"}],"name":"FixedPriceSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"NewAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldPendingAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newPendingAdmin","type":"address"}],"name":"NewPendingAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract ISolver","name":"oldSolver","type":"address"},{"indexed":false,"internalType":"contract ISolver","name":"newSolver","type":"address"}],"name":"NewSolver","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voucher","type":"address"},{"indexed":true,"internalType":"address","name":"issuer","type":"address"},{"components":[{"internalType":"uint24","name":"offeringId","type":"uint24"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"},{"internalType":"enum PriceManager.PriceType","name":"priceType","type":"uint8"},{"internalType":"uint128","name":"totalUnits","type":"uint128"},{"internalType":"uint128","name":"units","type":"uint128"},{"internalType":"uint128","name":"min","type":"uint128"},{"internalType":"uint128","name":"max","type":"uint128"},{"internalType":"address","name":"voucher","type":"address"},{"internalType":"address","name":"currency","type":"address"},{"internalType":"address","name":"issuer","type":"address"},{"internalType":"bool","name":"useAllowList","type":"bool"},{"internalType":"bool","name":"isValid","type":"bool"}],"indexed":false,"internalType":"struct OfferingMarketCore.Offering","name":"offering","type":"tuple"}],"name":"Offer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"issuer","type":"address"},{"indexed":true,"internalType":"uint24","name":"offeringId","type":"uint24"},{"indexed":false,"internalType":"address","name":"voucher","type":"address"},{"indexed":false,"internalType":"uint128","name":"total","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"sold","type":"uint128"}],"name":"Remove","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voucher","type":"address"}],"name":"RemoveMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"currency","type":"address"},{"indexed":false,"internalType":"bool","name":"enable","type":"bool"}],"name":"SetCurrency","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":true,"internalType":"uint24","name":"offeringId","type":"uint24"},{"indexed":true,"internalType":"address","name":"voucher","type":"address"},{"indexed":false,"internalType":"uint256","name":"voucherId","type":"uint256"},{"indexed":false,"internalType":"uint24","name":"tradeId","type":"uint24"},{"indexed":false,"internalType":"uint32","name":"tradeTime","type":"uint32"},{"indexed":false,"internalType":"address","name":"currency","type":"address"},{"indexed":false,"internalType":"uint8","name":"priceType","type":"uint8"},{"indexed":false,"internalType":"uint128","name":"price","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"tradedUnits","type":"uint128"},{"indexed":false,"internalType":"uint256","name":"tradedAmount","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"fee","type":"uint128"}],"name":"Traded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"voucher","type":"address"},{"indexed":false,"internalType":"uint256","name":"reduceAmount","type":"uint256"}],"name":"WithdrawFee","type":"event"},{"inputs":[],"name":"acceptAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"voucher_","type":"address"},{"internalType":"address[]","name":"addresses_","type":"address[]"},{"internalType":"bool","name":"resetExisting_","type":"bool"}],"name":"addAllowAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"voucher_","type":"address"},{"internalType":"address","name":"voucherPool_","type":"address"},{"internalType":"enum Constants.VoucherType","name":"voucherType_","type":"uint8"},{"internalType":"address","name":"asset_","type":"address"},{"internalType":"uint8","name":"decimals_","type":"uint8"},{"internalType":"uint16","name":"feeRate_","type":"uint16"},{"internalType":"bool","name":"onlyManangerOffer_","type":"bool"}],"name":"addMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint24","name":"offeringId_","type":"uint24"},{"internalType":"uint128","name":"units_","type":"uint128"}],"name":"buy","outputs":[{"internalType":"uint256","name":"amount_","type":"uint256"},{"internalType":"uint128","name":"fee_","type":"uint128"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint24","name":"offeringId_","type":"uint24"}],"name":"getDecliningPrice","outputs":[{"internalType":"uint128","name":"highest","type":"uint128"},{"internalType":"uint128","name":"lowest","type":"uint128"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"duration","type":"uint32"},{"internalType":"uint32","name":"interval","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint24","name":"offeringId_","type":"uint24"}],"name":"getFixedPrice","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint24","name":"offeringId_","type":"uint24"}],"name":"getPrice","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISolver","name":"solver_","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"voucher_","type":"address"},{"internalType":"address","name":"buyer_","type":"address"}],"name":"isBuyerAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum Constants.VoucherType","name":"voucherType_","type":"uint8"}],"name":"isSupportVoucherType","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"markets","outputs":[{"internalType":"enum Constants.VoucherType","name":"voucherType","type":"uint8"},{"internalType":"address","name":"voucherPool","type":"address"},{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint16","name":"feeRate","type":"uint16"},{"internalType":"bool","name":"onlyManangerOffer","type":"bool"},{"internalType":"bool","name":"isValid","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint24","name":"offeringId_","type":"uint24"}],"name":"mintParameters","outputs":[{"components":[{"internalType":"uint128","name":"lowestPrice","type":"uint128"},{"internalType":"uint128","name":"highestPrice","type":"uint128"},{"internalType":"uint128","name":"tokenInAmount","type":"uint128"},{"internalType":"uint64","name":"effectiveTime","type":"uint64"},{"internalType":"uint64","name":"maturity","type":"uint64"}],"internalType":"struct InitialConvertibleOfferingMarket.MintParameter","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextOfferingId","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextTradeId","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"voucher_","type":"address"},{"internalType":"address","name":"currency_","type":"address"},{"internalType":"uint128","name":"min_","type":"uint128"},{"internalType":"uint128","name":"max_","type":"uint128"},{"internalType":"uint32","name":"startTime_","type":"uint32"},{"internalType":"uint32","name":"endTime_","type":"uint32"},{"internalType":"bool","name":"useAllowList_","type":"bool"},{"internalType":"enum PriceManager.PriceType","name":"priceType_","type":"uint8"},{"internalType":"bytes","name":"priceData_","type":"bytes"},{"components":[{"internalType":"uint128","name":"lowestPrice","type":"uint128"},{"internalType":"uint128","name":"highestPrice","type":"uint128"},{"internalType":"uint128","name":"tokenInAmount","type":"uint128"},{"internalType":"uint64","name":"effectiveTime","type":"uint64"},{"internalType":"uint64","name":"maturity","type":"uint64"}],"internalType":"struct InitialConvertibleOfferingMarket.MintParameter","name":"mintParameter_","type":"tuple"}],"name":"offer","outputs":[{"internalType":"uint24","name":"offeringId","type":"uint24"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"voucher_","type":"address"},{"internalType":"uint256","name":"index_","type":"uint256"}],"name":"offeringIdOfvoucherByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint24","name":"","type":"uint24"}],"name":"offerings","outputs":[{"internalType":"uint24","name":"offeringId","type":"uint24"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"},{"internalType":"enum PriceManager.PriceType","name":"priceType","type":"uint8"},{"internalType":"uint128","name":"totalUnits","type":"uint128"},{"internalType":"uint128","name":"units","type":"uint128"},{"internalType":"uint128","name":"min","type":"uint128"},{"internalType":"uint128","name":"max","type":"uint128"},{"internalType":"address","name":"voucher","type":"address"},{"internalType":"address","name":"currency","type":"address"},{"internalType":"address","name":"issuer","type":"address"},{"internalType":"bool","name":"useAllowList","type":"bool"},{"internalType":"bool","name":"isValid","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint24","name":"offeringId_","type":"uint24"},{"internalType":"address","name":"buyer_","type":"address"}],"name":"purchasedUnits","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint24","name":"offeringId_","type":"uint24"}],"name":"remove","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"voucher_","type":"address"},{"internalType":"address[]","name":"addresses_","type":"address[]"}],"name":"removeAllowAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"voucher_","type":"address"}],"name":"removeMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"currency_","type":"address"},{"internalType":"bool","name":"enable_","type":"bool"}],"name":"setCurrency","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPendingAdmin_","type":"address"}],"name":"setPendingAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISolver","name":"newSolver_","type":"address"}],"name":"setSolver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"voucher_","type":"address"},{"internalType":"address[]","name":"managers_","type":"address[]"},{"internalType":"bool","name":"resetExisting_","type":"bool"}],"name":"setVoucherManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"solver","outputs":[{"internalType":"contract ISolver","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"voucher_","type":"address"}],"name":"totalOfferingsOfvoucher","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"voucher_","type":"address"}],"name":"voucherManagers","outputs":[{"internalType":"address[]","name":"managers_","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"currency_","type":"address"},{"internalType":"uint256","name":"reduceAmount_","type":"uint256"}],"name":"withdrawFee","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5061573e80620000216000396000f3fe6080604052600436106101685760003560e01c80630e18b6811461016d578063194e1660146101845780631d248d9a146101a45780631d442233146101c45780631f879433146101fa578063227845561461021a57806326782247146102475780633ac449171461026957806341ec4ef314610289578063423dd0dd146102aa57806349a7a26d146102d75780634d93e679146102ec5780634dd18bf51461030c5780635acc81071461032c57806363d0019a14610359578063813ad083146103865780638a31905f1461039b5780638e8f294b146103bb5780639627d763146103ee5780639ca24f341461040e5780639cfb2ab01461042e578063b63c47bb14610467578063bb21b32a14610487578063c39333ab1461049c578063c4d66de8146104c9578063c569a8f2146104e9578063d88ee8a914610509578063db91323614610529578063e0cc5f5a14610549578063f851a4401461057a578063fd9be5221461058f575b600080fd5b34801561017957600080fd5b506101826105af565b005b34801561019057600080fd5b5061018261019f366004614723565b610686565b3480156101b057600080fd5b506101826101bf366004614723565b6107b5565b3480156101d057600080fd5b506101e46101df366004614517565b6108bf565b6040516101f19190614c77565b60405180910390f35b34801561020657600080fd5b506101826102153660046144fb565b6108ea565b34801561022657600080fd5b5061023a6102353660046145ed565b610a3a565b6040516101f19190615377565b34801561025357600080fd5b5061025c610c72565b6040516101f191906149ee565b34801561027557600080fd5b50610182610284366004614788565b610c81565b61029c6102973660046148d6565b610d46565b6040516101f1929190615479565b3480156102b657600080fd5b506102ca6102c53660046148a1565b61103e565b6040516101f191906152fa565b3480156102e357600080fd5b5061025c61106f565b3480156102f857600080fd5b5061018261030736600461454f565b61107e565b34801561031857600080fd5b506101826103273660046144fb565b61127b565b34801561033857600080fd5b5061034c6103473660046144fb565b611341565b6040516101f19190614c2a565b34801561036557600080fd5b506103796103743660046147b5565b611426565b6040516101f19190615470565b34801561039257600080fd5b5061023a611448565b3480156103a757600080fd5b506102ca6103b63660046148bb565b61145a565b3480156103c757600080fd5b506103db6103d63660046144fb565b611492565b6040516101f19796959493929190614c9c565b3480156103fa57600080fd5b506101e46104093660046147fc565b6114ee565b34801561041a57600080fd5b506102ca6104293660046148a1565b611505565b34801561043a57600080fd5b5061044e6104493660046148a1565b611525565b6040516101f19d9c9b9a999897969594939291906153c6565b34801561047357600080fd5b506103796104823660046144fb565b6115cd565b34801561049357600080fd5b5061023a6115ee565b3480156104a857600080fd5b506104bc6104b73660046148a1565b611600565b6040516101f1919061519e565b3480156104d557600080fd5b506101826104e43660046144fb565b61167c565b3480156104f557600080fd5b506101826105043660046148a1565b61175f565b34801561051557600080fd5b506101826105243660046146d1565b611b07565b34801561053557600080fd5b506101826105443660046144fb565b611bf3565b34801561055557600080fd5b506105696105643660046148a1565b611cbb565b6040516101f195949392919061533f565b34801561058657600080fd5b5061025c611d0d565b34801561059b57600080fd5b506101826105aa3660046147b5565b611d1c565b6036546001600160a01b03166105c3611dc1565b6001600160a01b031614610613576040805162461bcd60e51b815260206004820152601260248201527137b7363c903832b73234b7339030b236b4b760711b604482015290519081900360640190fd5b603554603654604080516001600160a01b03938416815292909116602083015280517ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc9281900390910190a160368054603580546001600160a01b03199081166001600160a01b03841617909155169055565b60355484906001600160a01b03163314806106be57506001600160a01b03811660009081526071602052604090206106be9033611dc5565b6106e35760405162461bcd60e51b81526004016106da90614ee6565b60405180910390fd5b6001600160a01b0385166000908152606a6020526040902060010154600160c01b900460ff166107255760405162461bcd60e51b81526004016106da90614e94565b6001600160a01b0385166000908152607060205260409020821561076d575b61074d81611dda565b1561076d57610767610760826000611de5565b8290611df1565b50610744565b60005b848110156107ac576107a386868381811061078757fe5b905060200201602081019061079c91906144fb565b8390611e06565b50600101610770565b50505050505050565b6035546001600160a01b03166107c9611dc1565b6001600160a01b031614610811576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9030b236b4b760b11b604482015290519081900360640190fd5b6001600160a01b0384166000908152606a6020526040902060010154600160c01b900460ff166108535760405162461bcd60e51b81526004016106da90614e94565b6001600160a01b03841660009081526071602052604090208115610894575b61087b81611dda565b156108945761088e610760826000611de5565b50610872565b60005b838110156108b7576108ae85858381811061078757fe5b50600101610897565b505050505050565b6001600160a01b03821660009081526070602052604081206108e19083611dc5565b90505b92915050565b6035546001600160a01b03166108fe611dc1565b6001600160a01b031614610946576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9030b236b4b760b11b604482015290519081900360640190fd5b60735460408051630305538f60e11b815290516001600160a01b039283169284169163060aa71e916004808301926020929190829003018186803b15801561098d57600080fd5b505afa1580156109a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c591906147e0565b6109e15760405162461bcd60e51b81526004016106da90615147565b607380546001600160a01b0319166001600160a01b0384161790556040517f75d88007781bda78ca68e333bfe4f9e91473720b4be5c63ee715949839afe7c790610a2e9083908590614c82565b60405180910390a15050565b6001600160a01b038b166000908152606a6020526040808220815160e08101909252805483929190829060ff166002811115610a7257fe5b6002811115610a7d57fe5b815281546001600160a01b036101009091048116602080840191909152600190930154808216604084015260ff600160a01b82048116606085015261ffff600160a81b8304166080850152600160b81b82048116151560a0850152600160c01b90910416151560c09092019190915282820151929350919091169063dd3cb01f9033908f90610b0e90880188614816565b610b1e6040890160208a01614816565b610b2e60808a0160608b0161493c565b610b3e60a08b0160808c0161493c565b60006040518863ffffffff1660e01b8152600401610b629796959493929190614a02565b60006040518083038186803b158015610b7a57600080fd5b505afa158015610b8e573d6000803e3d6000fd5b5060009250610bc69150610ba790506020860186614816565b610bb76060870160408801614816565b6001600160801b031690611e1b565b9050610bf2826040015133866040016020810190610be49190614816565b6001600160801b0316611e95565b50610c3b8e8e838f8f8f8f8f8f8f8f8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061226092505050565b62ffffff811660009081526074602052604090209093508490610c5e8282615514565b90505050509b9a5050505050505050505050565b6036546001600160a01b031681565b6035546001600160a01b0316610c95611dc1565b6001600160a01b031614610cdd576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9030b236b4b760b11b604482015290519081900360640190fd5b8015610cf457610cee606b83611e06565b50610d01565b610cff606b83611df1565b505b816001600160a01b03167f98c0c4bde5f642566cdaebfb7cd2cdc72a98bc7f3440e38c19e1d58d92388d3482604051610d3a9190614c77565b60405180910390a25050565b60008060026037541415610d8f576040805162461bcd60e51b815260206004820152601f6024820152600080516020615677833981519152604482015290519081900360640190fd5b6002603755336000610da08661103e565b62ffffff87166000908152606960205260409020600581015491925090600160a81b900460ff16610de35760405162461bcd60e51b81526004016106da906150c2565b60038101546001600160a01b03166000908152606a6020526040808220815160e081019092528054829060ff166002811115610e1b57fe5b6002811115610e2657fe5b815281546001600160a01b0361010090910481166020830152600190920154918216604082015260ff600160a01b83048116606083015261ffff600160a81b8404166080830152600160b81b83048116151560a0830152600160c01b909204909116151560c091820152810151909150610eb25760405162461bcd60e51b81526004016106da90614dbd565b6060810151610edd9060ff16600a0a610ed76001600160801b038a8116908716612a28565b90612a81565b6003830154909650610ef8906001600160a01b031687612ae5565b60735460038401546040519297506000926001600160a01b039283169263a4888f1792610f34929116908d908a908d908f908c90602001614bcb565b6040516020818303038152906040526040518263ffffffff1660e01b8152600401610f5f9190614fd9565b602060405180830381600087803b158015610f7957600080fd5b505af1158015610f8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb19190614901565b90508015610fd15760405162461bcd60e51b81526004016106da90614e3b565b60006040518060a00160405280876001600160a01b031681526020018981526020018a6001600160801b03168152602001866001600160801b03168152602001886001600160801b0316815250905061102a8482612b53565b505050505050600160375590939092509050565b62ffffff811660009081526069602052604081205461106790600160581b900460ff16836130d4565b90505b919050565b6073546001600160a01b031681565b6035546001600160a01b0316611092611dc1565b6001600160a01b0316146110da576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9030b236b4b760b11b604482015290519081900360640190fd5b6110e5606d88611dc5565b156111025760405162461bcd60e51b81526004016106da90614f2e565b61110b856114ee565b6111275760405162461bcd60e51b81526004016106da90614d61565b61271061ffff8316111561114d5760405162461bcd60e51b81526004016106da90615036565b6001600160a01b038781166000908152606a602052604090208054610100600160a81b031916610100928916929092029190911780825560018083018054600160c01b60ff60c01b199091161760ff60a01b1916600160a01b60ff8916021761ffff60a81b1916600160a81b61ffff88160217905587929160ff1916908360028111156111d657fe5b02179055506001600160a01b038781166000908152606a6020526040902060010180546001600160a01b0319169186169190911760ff60b81b1916600160b81b83151502179055611228606d88611e06565b50866001600160a01b03167f4726a3debe773e4dc7b92dcafbff82d7a6498ac37767a4551768687b986e7ac3868686868660405161126a959493929190614cf1565b60405180910390a250505050505050565b6035546001600160a01b031661128f611dc1565b6001600160a01b0316146112d7576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9030b236b4b760b11b604482015290519081900360640190fd5b603654604080516001600160a01b039283168152918316602083015280517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a99281900390910190a1603680546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038116600090815260716020526040902060609061136590611dda565b6001600160401b038111801561137a57600080fd5b506040519080825280602002602001820160405280156113a4578160200160208202803683370190505b50905060005b6001600160a01b03831660009081526071602052604090206113cb90611dda565b811015611420576001600160a01b03831660009081526071602052604090206113f49082611de5565b82828151811061140057fe5b6001600160a01b03909216602092830291909101909101526001016113aa565b50919050565b6001600160a01b0382166000908152606f602052604081206108e19083611de5565b607354600160b81b900462ffffff1681565b62ffffff821660009081526072602090815260408083206001600160a01b03851684529091529020546001600160801b031692915050565b606a602052600090815260409020805460019091015460ff808316926001600160a01b0361010090910481169290811691600160a01b820481169161ffff600160a81b82041691600160b81b8204811691600160c01b90041687565b600060028260028111156114fe57fe5b1492915050565b62ffffff166000908152600160205260409020546001600160801b031690565b60696020526000908152604090208054600182015460028301546003840154600485015460059095015462ffffff85169563ffffffff63010000008704811696600160381b81049091169560ff600160581b83048116966001600160801b03600160601b90940484169683851696600160801b90940485169591909416936001600160a01b03908116939181169290821691600160a01b8104821691600160a81b909104168d565b6001600160a01b0381166000908152606f6020526040812061106790611dda565b607354600160a01b900462ffffff1681565b6116086143d4565b5062ffffff16600090815260746020908152604091829020825160a08101845281546001600160801b038082168352600160801b918290048116948301949094526001909201549283169381019390935281046001600160401b039081166060840152600160c01b90910416608082015290565b600254610100900460ff168061169557506116956132ee565b806116a3575060025460ff16155b6116de5760405162461bcd60e51b815260040180806020018281038252602e8152602001806156ba602e913960400191505060405180910390fd5b600254610100900460ff16158015611709576002805460ff1961ff0019909116610100171660011790555b6117116132ff565b61171a336133a9565b6073805462ffffff60b81b1962ffffff60a01b19909116600160a01b1716600160b81b179055611749826108ea565b801561175b576002805461ff00191690555b5050565b600260375414156117a5576040805162461bcd60e51b815260206004820152601f6024820152600080516020615677833981519152604482015290519081900360640190fd5b600260375562ffffff808216600090815260696020908152604080832081516101a0810183528154958616815263ffffffff63010000008704811694820194909452600160381b8604909316918301919091529192909190606083019060ff600160581b90910416600181111561181857fe5b600181111561182357fe5b815281546001600160801b03600160601b9091048116602083015260018301548082166040840152600160801b900481166060830152600283015416608082015260038201546001600160a01b0390811660a08301526004830154811660c083015260059092015491821660e082015260ff600160a01b830481161515610100830152600160a81b9092049091161515610120909101526101808101519091506118df5760405162461bcd60e51b81526004016106da906150c2565b6101408101516001600160a01b0316331461190c5760405162461bcd60e51b81526004016106da90614ec1565b806020015163ffffffff1642108061192d5750806040015163ffffffff1642115b6119495760405162461bcd60e51b81526004016106da9061511a565b60735461010082015182516101408401516040516000946001600160a01b03169363a4888f1793611981939192909190602001614ba3565b6040516020818303038152906040526040518263ffffffff1660e01b81526004016119ac9190615060565b602060405180830381600087803b1580156119c657600080fd5b505af11580156119da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119fe9190614901565b90508015611a1e5760405162461bcd60e51b81526004016106da90614e3b565b611a2c838360a00151613466565b816000015162ffffff168261014001516001600160a01b03167fbb370dc13b0902f591e63a63b13cbda9ce623e87fac2b5de368df00fc2f9cafb84610100015185608001518660a00151876080015103604051611a8b93929190614b5b565b60405180910390a3505062ffffff16600090815260696020526040812080546001600160e01b03191681556001808201929092556002810180546001600160801b03191690556003810180546001600160a01b0319908116909155600482018054909116905560050180546001600160b01b0319169055603755565b60355483906001600160a01b0316331480611b3f57506001600160a01b0381166000908152607160205260409020611b3f9033611dc5565b611b5b5760405162461bcd60e51b81526004016106da90614ee6565b6001600160a01b0384166000908152606a6020526040902060010154600160c01b900460ff16611b9d5760405162461bcd60e51b81526004016106da90614e94565b6001600160a01b0384166000908152607060205260408120905b838110156108b757611bea858583818110611bce57fe5b9050602002016020810190611be391906144fb565b8390611df1565b50600101611bb7565b6035546001600160a01b0316611c07611dc1565b6001600160a01b031614611c4f576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9030b236b4b760b11b604482015290519081900360640190fd5b611c5a606d82611df1565b506001600160a01b0381166000818152606a602052604080822080546001600160a81b031916815560010180546001600160c81b0319169055517fc14aef421d4ad67b24691f0e51a4706ba86588e0a70f137686bffee5e0b0b5089190a250565b62ffffff16600090815260208190526040902080546001909101546001600160801b0380831693600160801b909304169163ffffffff80831692600160201b8104821692600160401b90910490911690565b6035546001600160a01b031681565b6035546001600160a01b0316611d30611dc1565b6001600160a01b031614611d78576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9030b236b4b760b11b604482015290519081900360640190fd5b603554611d909083906001600160a01b03168361368e565b7f66bf9186b00db666fc37aaffbb95a050c66e599e000c785c1dff0467d868f1b18282604051610a2e929190614c11565b3390565b60006108e1836001600160a01b0384166138f7565b60006110678261390f565b60006108e18383613913565b60006108e1836001600160a01b038416613977565b60006108e1836001600160a01b038416613a3d565b60006001600160801b038316611e33575060006108e4565b8282026001600160801b038084169080861690831681611e4f57fe5b046001600160801b0316146108e15760405162461bcd60e51b81526004018080602001828103825260218152602001806156e86021913960400191505060405180910390fd5b60006001600160a01b03841673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415611f6a57326001600160a01b0384161480611edb5750336001600160a01b038416145b611f1e576040805162461bcd60e51b815260206004820152600f60248201526e0e6cadcc8cae440dad2e6dac2e8c6d608b1b604482015290519081900360640190fd5b813414611f63576040805162461bcd60e51b815260206004820152600e60248201526d0ecc2d8eaca40dad2e6dac2e8c6d60931b604482015290519081900360640190fd5b5080612259565b3415611fb7576040805162461bcd60e51b8152602060048201526017602482015276646f6e277420737570706f7274206d73672e76616c756560481b604482015290519081900360640190fd5b6000846001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561200657600080fd5b505afa15801561201a573d6000803e3d6000fd5b505050506040513d602081101561203057600080fd5b5051604080516001600160a01b038781166024830152306044830152606480830188905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b178152925182519495506000948594928b16939282918083835b602083106120b55780518252601f199092019160209182019101612096565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612117576040519150601f19603f3d011682016040523d82523d6000602084013e61211c565b606091505b509150915081801561214a57508051158061214a575080806020019051602081101561214757600080fd5b50515b612181576040805162461bcd60e51b815260206004820152600360248201526229aa2360e91b604482015290519081900360640190fd5b6000876001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156121d057600080fd5b505afa1580156121e4573d6000803e3d6000fd5b505050506040513d60208110156121fa57600080fd5b5051905083811015612250576040805162461bcd60e51b815260206004820152601a602482015279544f4b454e5f5452414e534645525f494e5f4f564552464c4f5760301b604482015290519081900360640190fd5b92909203925050505b9392505050565b6000600260375414156122a8576040805162461bcd60e51b815260206004820152601f6024820152600080516020615677833981519152604482015290519081900360640190fd5b60026037556001600160a01b038b16158015906122cd57506001600160a01b038a1615155b6122e95760405162461bcd60e51b81526004016106da90614d34565b6001600160a01b038b166000908152606a6020526040808220815160e081019092528054829060ff16600281111561231d57fe5b600281111561232857fe5b815281546001600160a01b0361010090910481166020830152600190920154918216604082015260ff600160a01b83048116606083015261ffff600160a81b8404166080830152600160b81b83048116151560a0830152600160c01b909204909116151560c0918201528101519091506123b45760405162461bcd60e51b81526004016106da90614e94565b6123bf606b8c611dc5565b6123db5760405162461bcd60e51b81526004016106da906150ec565b8663ffffffff168663ffffffff16116124065760405162461bcd60e51b81526004016106da90614f81565b8060a001511561244e576001600160a01b038c1660009081526071602052604090206124329033611dc5565b61244e5760405162461bcd60e51b81526004016106da90614ee6565b6001600160801b0388161561248f57876001600160801b0316896001600160801b0316111561248f5760405162461bcd60e51b81526004016106da90614fb6565b6000607360009054906101000a90046001600160a01b03166001600160a01b031663a4888f178e338f8f8f8f8f8f8f8f8f6040516020016124da9b9a99989796959493929190614a57565b6040516020818303038152906040526040518263ffffffff1660e01b8152600401612505919061516f565b602060405180830381600087803b15801561251f57600080fd5b505af1158015612533573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125579190614901565b905080156125775760405162461bcd60e51b81526004016106da90614f55565b61257f613a87565b9250604051806101a001604052808462ffffff1681526020018963ffffffff1681526020018863ffffffff1681526020018660018111156125bc57fe5b81526020018c6001600160801b031681526020018c6001600160801b031681526020018b6001600160801b031681526020018a6001600160801b031681526020018e6001600160a01b031681526020018d6001600160a01b03168152602001336001600160a01b03168152602001871515815260200160011515815250606960008562ffffff1662ffffff16815260200190815260200160002060008201518160000160006101000a81548162ffffff021916908362ffffff16021790555060208201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160076101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001600b6101000a81548160ff021916908360018111156126ed57fe5b0217905550608082015181546001600160801b03918216600160601b02600160601b600160e01b031990911617825560a08301516001808401805460c08701518516600160801b029385166001600160801b031991821617851693909317905560e0850151600285018054919094169216919091179091556101008301516003830180546001600160a01b039283166001600160a01b03199182161790915561012085015160048501805491841691831691909117905561014085015160059094018054610160870151610180909701511515600160a81b0260ff60a81b19971515600160a01b0260ff60a01b1997909516919093161794909416919091179390931692909217905562ffffff808516600090815260696020908152604080832081516101a0810183528154958616815263ffffffff63010000008704811694820194909452600160381b860490931691830191909152919390926060840191600160581b90910460ff169081111561286257fe5b600181111561286d57fe5b815281546001600160801b03600160601b9091048116602083015260018301548082166040840152600160801b900481166060830152600283015416608082015260038201546001600160a01b0390811660a08301526004830154811660c083015260059092015491821660e082015260ff600160a01b830481161515610100830152600160a81b9092049091161515610120909101529050612911818787613ab6565b60735461010082015182516040516001600160a01b0390931692635e9d02539261293f929091602001614b85565b6040516020818303038152906040526040518263ffffffff1660e01b815260040161296a919061516f565b602060405180830381600087803b15801561298457600080fd5b505af1158015612998573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129bc9190614901565b508061014001516001600160a01b03168161010001516001600160a01b03167f11e21d4c53b5f1e70b770c9195d73d66e48ac66695686c9022be6f6acaeb74dd83604051612a0a91906151f2565b60405180910390a350505060016037559a9950505050505050505050565b600082612a37575060006108e4565b82820282848281612a4457fe5b04146108e15760405162461bcd60e51b81526004018080602001828103825260218152602001806156e86021913960400191505060405180910390fd5b6000808211612ad4576040805162461bcd60e51b815260206004820152601a602482015279536166654d6174683a206469766973696f6e206279207a65726f60301b604482015290519081900360640190fd5b818381612add57fe5b049392505050565b6001600160a01b0382166000908152606a6020526040812060018101548290612b229061271090610ed7908790600160a81b900461ffff16612a28565b90506001600160801b03811115612b4b5760405162461bcd60e51b81526004016106da90615090565b949350505050565b6005820154600160a81b900460ff16612b7e5760405162461bcd60e51b81526004016106da90614d93565b60018201546001600160801b0316612ba85760405162461bcd60e51b81526004016106da90614f0c565b81546301000000900463ffffffff164210801590612bd457508154600160381b900463ffffffff164211155b612bf05760405162461bcd60e51b81526004016106da90614de5565b6005820154600160a01b900460ff1615612c4757805160038301546001600160a01b03166000908152607060205260409020612c2b91611dc5565b612c475760405162461bcd60e51b81526004016106da90614e10565b60018201546001600160801b03600160801b82048116911610612ca057600182015460408201516001600160801b03600160801b909204821691161015612ca05760405162461bcd60e51b81526004016106da90614e68565b60028201546001600160801b031615612d7457604080820151835462ffffff1660009081526072602090815283822085516001600160a01b03168352905291822054612cf7916001600160801b0390911690613bea565b60028401549091506001600160801b039081169082161115612d2b5760405162461bcd60e51b81526004016106da90615006565b825462ffffff16600090815260726020908152604080832085516001600160a01b03168452909152902080546001600160801b0319166001600160801b03929092169190911790555b6040808201518151808301909252601b82527a696e73756666696369656e7420756e69747320666f722073616c6560281b60208301526001840154612dc5926001600160801b039091169190613c4e565b6001830180546001600160801b0319166001600160801b0392909216919091179055612def614402565b602080830180518352608084015160408051808201909152601281527119995948195e18d959591cc8185b5bdd5b9d60721b938101939093529051612e3f9290916001600160801b031690613cf8565b602080830191909152604080516101a081018252855462ffffff8116825263ffffffff63010000008204811694830194909452600160381b810490931691810191909152600091612f6c91908690606083019060ff600160581b909104166001811115612ea857fe5b6001811115612eb357fe5b815281546001600160801b03600160601b90910481166020808401919091526001840154808316604080860191909152600160801b909104831660608501526002850154909216608084015260038401546001600160a01b0390811660a08501526004850154811660c085015260059094015493841660e084015260ff600160a01b850481161515610100850152600160a81b909404909316151561012090920191909152865186519188015192870151909290613d4a565b607354855485516020808801516040808a015160808b015191519798506001600160a01b0390961696635e9d025396612faf9662ffffff16959490929101615387565b6040516020818303038152906040526040518263ffffffff1660e01b8152600401612fda9190614fd9565b602060405180830381600087803b158015612ff457600080fd5b505af1158015613008573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061302c9190614901565b506003840154845484516001600160a01b039283169262ffffff90921691167f6652b98f9bca9e2eb651f3f44cab9bc07d80b17367ee7e958466c79e9e67f75284613075613d99565b60048a01548a5442916001600160a01b031690600160581b900460ff16600181111561309d57fe5b8b606001518c604001518d602001518e608001516040516130c699989796959493929190615490565b60405180910390a450505050565b6000808360018111156130e357fe5b141561310d575062ffffff81166000908152600160205260409020546001600160801b03166108e4565b600183600181111561311b57fe5b14156132a95762ffffff82166000908152602081905260409020600181015463ffffffff808216600160201b90920481169190910116421061316f5754600160801b90046001600160801b031690506108e4565b600181015463ffffffff16421161319157546001600160801b031690506108e4565b6001810154815460009163ffffffff600160201b8204811692600160401b909204166001600160801b03600160801b83048116928116929092030216816131d457fe5b60018401549190046001600160801b031690600160401b810463ffffffff908116911642038161320057fe5b8454919004919091026001600160801b03808316919091039250600091600160801b90041682106132315781613244565b8254600160801b90046001600160801b03165b90506001600160801b0381111561329f576040805162461bcd60e51b815260206004820152601a6024820152790e0e4d2c6ca7440caf0c6cacac8e640ead2dce862647040dac2f60331b604482015290519081900360640190fd5b92506108e4915050565b6040805162461bcd60e51b8152602060048201526015602482015274756e737570706f727465642070726963655479706560581b604482015290519081900360640190fd5b60006132f930613dc8565b15905090565b600254610100900460ff168061331857506133186132ee565b80613326575060025460ff16155b6133615760405162461bcd60e51b815260040180806020018281038252602e8152602001806156ba602e913960400191505060405180910390fd5b600254610100900460ff1615801561338c576002805460ff1961ff0019909116610100171660011790555b613394613dce565b80156133a6576002805461ff00191690555b50565b600254610100900460ff16806133c257506133c26132ee565b806133d0575060025460ff16155b61340b5760405162461bcd60e51b815260040180806020018281038252602e8152602001806156ba602e913960400191505060405180910390fd5b600254610100900460ff16158015613436576002805460ff1961ff0019909116610100171660011790555b603580546001600160a01b0319166001600160a01b038416179055801561175b576002805461ff00191690555050565b62ffffff808316600090815260696020908152604080832081516101a0810183528154958616815263ffffffff63010000008704811694820194909452600160381b8604909316918301919091529192909190606083019060ff600160581b9091041660018111156134d457fe5b60018111156134df57fe5b815281546001600160801b03600160601b9091048116602080840191909152600180850154808416604080870191909152600160801b909104841660608601526002860154909316608085015260038501546001600160a01b0390811660a0860152600480870154821660c087015260059096015480821660e087015260ff600160a01b82048116151561010080890191909152600160a81b909204161515610120909601959095529386015184166000908152606a909252828220015491516370a0823160e01b8152949550911692909183916370a08231916135c5913091016149ee565b60206040518083038186803b1580156135dd57600080fd5b505afa1580156135f1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136159190614901565b62ffffff861660009081526074602052604081205491925090613644906001600160801b038781169116613e74565b6001600160801b031690508181111561365a5750805b6101008401516001600160a01b039081166000908152606a60205260409020600101546101408601516108b7929190911690835b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156137a857604080516000808252602082019092526001600160a01b0384169083906040518082805190602001908083835b602083106136ff5780518252601f1990920191602091820191016136e0565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613761576040519150601f19603f3d011682016040523d82523d6000602084013e613766565b606091505b50509050806137a2576040805162461bcd60e51b815260206004820152600360248201526253544560e81b604482015290519081900360640190fd5b506138f2565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1781529251825160009485949389169392918291908083835b602083106138245780518252601f199092019160209182019101613805565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114613886576040519150601f19603f3d011682016040523d82523d6000602084013e61388b565b606091505b50915091508180156138b95750805115806138b957508080602001905160208110156138b657600080fd5b50515b6138ef576040805162461bcd60e51b815260206004820152600260248201526114d560f21b604482015290519081900360640190fd5b50505b505050565b60009081526001919091016020526040902054151590565b5490565b815460009082106139555760405162461bcd60e51b81526004018080602001828103825260228152602001806156556022913960400191505060405180910390fd5b82600001828154811061396457fe5b9060005260206000200154905092915050565b60008181526001830160205260408120548015613a3357835460001980830191908101906000908790839081106139aa57fe5b90600052602060002001549050808760000184815481106139c757fe5b6000918252602080832090910192909255828152600189810190925260409020908401905586548790806139f757fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506108e4565b60009150506108e4565b6000613a4983836138f7565b613a7f575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556108e4565b5060006108e4565b6073805462ffffff60a01b198116600160a01b9182900462ffffff908116600181019091169092021790915590565b6000826001811115613ac457fe5b1415613b5357600081806020019051810190613ae09190614832565b9050613af0846000015182613eeb565b836000015162ffffff168461010001516001600160a01b03167fdb309e75ed206bcf93ed0bb2cb6bfac9fb3e900bd97d454a342100e5fee8cc98856001811115613b3657fe5b84604051613b459291906154f8565b60405180910390a3506138f2565b60008060008084806020019051810190613b6d919061484e565b9350935093509350613b8b8760000151886020015186868686613f20565b866000015162ffffff168761010001516001600160a01b03167fa1129f336ddb4d6d6b397fffdf78e9a43ff20e0420bdf3d7244c98278de92f6886868686604051613bd9949392919061530e565b60405180910390a350505050505050565b60008282016001600160801b0380851690821610156108e1576040805162461bcd60e51b815260206004820152601b60248201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604482015290519081900360640190fd5b6000836001600160801b0316836001600160801b031611158290613cf05760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613cb5578181015183820152602001613c9d565b50505050905090810190601f168015613ce25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008184841115613cf05760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613cb5578181015183820152602001613c9d565b6000613d5c8661012001518686611e95565b508551613d699084614062565b9050613d7b866101000151868361435e565b613d908661012001518761014001518461368e565b95945050505050565b6073805462ffffff60b81b198116600160b81b9182900462ffffff908116600181019091169092021790915590565b3b151590565b600254610100900460ff1680613de75750613de76132ee565b80613df5575060025460ff16155b613e305760405162461bcd60e51b815260040180806020018281038252602e8152602001806156ba602e913960400191505060405180910390fd5b600254610100900460ff16158015613e5b576002805460ff1961ff0019909116610100171660011790555b600160375580156133a6576002805461ff001916905550565b600080826001600160801b031611613ed0576040805162461bcd60e51b815260206004820152601a602482015279536166654d6174683a206469766973696f6e206279207a65726f60301b604482015290519081900360640190fd5b816001600160801b0316836001600160801b031681612add57fe5b62ffffff91909116600090815260016020526040902080546001600160801b0319166001600160801b03909216919091179055565b826001600160801b0316846001600160801b031611613f86576040805162461bcd60e51b815260206004820181905260248201527f68696768657374206d7573742067726561746572207468616e206c6f77657374604482015290519081900360640190fd5b8063ffffffff168263ffffffff161015613fd15760405162461bcd60e51b81526004018080602001828103825260238152602001806156976023913960400191505060405180910390fd5b62ffffff95909516600090815260208190526040902060018101805482546001600160801b0319166001600160801b03968716178616600160801b959096169490940294909417905563ffffffff1990911663ffffffff9384161763ffffffff60201b1916600160201b918416919091021763ffffffff60401b1916600160401b9290931691909102919091179055565b62ffffff808316600090815260696020908152604080832081516101a0810183528154958616815263ffffffff63010000008704811694820194909452600160381b8604909316918301919091529192839290606083019060ff600160581b9091041660018111156140d057fe5b60018111156140db57fe5b815281546001600160801b03600160601b9091048116602080840191909152600180850154808416604080870191909152600160801b9182900485166060808801919091526002880154861660808089019190915260038901546001600160a01b0390811660a0808b019190915260048b0154821660c08b01526005909a015490811660e08a015260ff600160a01b8204811615156101008b0152600160a81b9091041615156101209098019790975262ffffff8d166000908152607486528281208351998a0184528054808916808c52908690048916978b019790975290940154808716928901929092526001600160401b03928204831690880152600160c01b90041693850193909352939450919290916141fb9190871690613e74565b61010080850180516001600160a01b039081166000908152606a6020526040808220600101549351831682529081902054905163095ea7b360e01b81529495509181169363095ea7b3936142589304909116908590600401614b39565b602060405180830381600087803b15801561427257600080fd5b505af1158015614286573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142aa91906147e0565b508261010001516001600160a01b031663b9dacaf38461014001518561012001518560000151866020015187606001518860800151886040518863ffffffff1660e01b81526004016143029796959493929190614ae7565b6040805180830381600087803b15801561431b57600080fd5b505af115801561432f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143539190614919565b979650505050505050565b604080516323b872dd60e01b81523060048201526001600160a01b03848116602483015260448201849052915185928316916323b872dd91606480830192600092919082900301818387803b1580156143b657600080fd5b505af11580156143ca573d6000803e3d6000fd5b5050505050505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b604051806040016040528060008152602001600081525090565b60008083601f84011261442d578182fd5b5081356001600160401b03811115614443578182fd5b602083019150836020808302850101111561445d57600080fd5b9250929050565b803561106a8161560a565b60008083601f840112614480578182fd5b5081356001600160401b03811115614496578182fd5b60208301915083602082850101111561445d57600080fd5b80356002811061106a57600080fd5b80356003811061106a57600080fd5b600060a08284031215611420578081fd5b803562ffffff8116811461106a57600080fd5b803561106a8161562d565b60006020828403121561450c578081fd5b81356108e1816155f5565b60008060408385031215614529578081fd5b8235614534816155f5565b91506020830135614544816155f5565b809150509250929050565b600080600080600080600060e0888a031215614569578283fd5b8735614574816155f5565b96506020880135614584816155f5565b9550614592604089016144bd565b945060608801356145a2816155f5565b9350608088013560ff811681146145b7578384fd5b925060a088013561ffff811681146145cd578283fd5b915060c08801356145dd8161560a565b8091505092959891949750929550565b60008060008060008060008060008060006101c08c8e03121561460e578384fd5b8b35614619816155f5565b9a5060208c0135614629816155f5565b995060408c013561463981615618565b985060608c013561464981615618565b975060808c01356146598161562d565b965061466760a08d016144f0565b955061467560c08d01614464565b945061468360e08d016144ae565b93506101008c01356001600160401b0381111561469e578384fd5b6146aa8e828f0161446f565b90945092506146bf90508d6101208e016144cc565b90509295989b509295989b9093969950565b6000806000604084860312156146e5578283fd5b83356146f0816155f5565b925060208401356001600160401b0381111561470a578283fd5b6147168682870161441c565b9497909650939450505050565b60008060008060608587031215614738578182fd5b8435614743816155f5565b935060208501356001600160401b0381111561475d578283fd5b6147698782880161441c565b909450925050604085013561477d8161560a565b939692955090935050565b6000806040838503121561479a578182fd5b82356147a5816155f5565b915060208301356145448161560a565b600080604083850312156147c7578182fd5b82356147d2816155f5565b946020939093013593505050565b6000602082840312156147f1578081fd5b81516108e18161560a565b60006020828403121561480d578081fd5b6108e1826144bd565b600060208284031215614827578081fd5b81356108e181615618565b600060208284031215614843578081fd5b81516108e181615618565b60008060008060808587031215614863578182fd5b845161486e81615618565b602086015190945061487f81615618565b60408601519093506148908161562d565b606086015190925061477d8161562d565b6000602082840312156148b2578081fd5b6108e1826144dd565b600080604083850312156148cd578182fd5b614534836144dd565b600080604083850312156148e8578182fd5b6148f1836144dd565b9150602083013561454481615618565b600060208284031215614912578081fd5b5051919050565b6000806040838503121561492b578182fd5b505080516020909101519092909150565b60006020828403121561494d578081fd5b81356108e18161563f565b6001600160a01b03169052565b15159052565b60008151808452815b8181101561499057602081850181015186830182015201614974565b818111156149a15782602083870101525b50601f01601f19169290920160200192915050565b600281106149c057fe5b9052565b600381106149c057fe5b6001600160801b03169052565b62ffffff169052565b63ffffffff169052565b6001600160a01b0391909116815260200190565b6001600160a01b0397881681529590961660208601526001600160801b0393841660408601529190921660608401526001600160401b0391821660808401521660a082015260ff90911660c082015260e00190565b6001600160a01b038c811682528b811660208301528a1660408201526001600160801b0389811660608301528881166080830152871660a082015263ffffffff86811660c0830152851660e08201528315156101008201526000610160614ac26101208401866149b6565b80610140840152614ad58184018561496b565b9e9d5050505050505050505050505050565b6001600160a01b0397881681529590961660208601526001600160801b03938416604086015291831660608501526001600160401b0390811660808501521660a083015290911660c082015260e00190565b6001600160a01b039290921682526001600160801b0316602082015260400190565b6001600160a01b039390931683526001600160801b03918216602084015216604082015260600190565b6001600160a01b0392909216825262ffffff16602082015260400190565b6001600160a01b03938416815262ffffff929092166020830152909116604082015260600190565b6001600160a01b03968716815262ffffff95909516602086015292909416604084015260608301526001600160801b03928316608083015290911660a082015260c00190565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b81811015614c6b5783516001600160a01b031683529284019291840191600101614c46565b50909695505050505050565b901515815260200190565b6001600160a01b0392831681529116602082015260400190565b60e08101614caa828a6149c4565b6001600160a01b03978816602083015295909616604087015260ff93909316606086015261ffff919091166080850152151560a0840152151560c090920191909152919050565b60a08101614cff82886149c4565b6001600160a01b0395909516602082015260ff93909316604084015261ffff9190911660608301521515608090910152919050565b6020808252601390820152720616464726573732063616e6e6f74206265203606c1b604082015260600190565b602080825260189082015277756e737570706f7274656420766f7563686572207479706560401b604082015260600190565b60208082526010908201526f1bd999995c9a5b99c81a5b9d985b1a5960821b604082015260600190565b6020808252600e908201526d1a5b9d985b1a59081b585c9ad95d60921b604082015260600190565b6020808252601190820152706e6f74206f66666572696e672074696d6560781b604082015260600190565b6020808252601190820152701b9bdd081a5b88185b1b1bddc81b1a5cdd607a1b604082015260600190565b60208082526013908201527214dbdb1d995c8e881b9bdd08185b1b1bddd959606a1b604082015260600190565b6020808252601290820152711b5a5b88185b5bdd5b9d081b9bdd081b595d60721b604082015260600190565b6020808252601390820152723ab739bab83837b93a32b2103b37bab1b432b960691b604082015260600190565b6020808252600b908201526a37b7363c9034b9b9bab2b960a91b604082015260600190565b6020808252600c908201526b37b7363c9036b0b730b3b2b960a11b604082015260600190565b6020808252600890820152671cdbdb19081bdd5d60c21b604082015260600190565b6020808252600d908201526c185b1c9958591e481859191959609a1b604082015260600190565b6020808252601290820152711cdbdb1d995c881b9bdd08185b1b1bddd95960721b604082015260600190565b6020808252601b908201527a656e6454696d65206c657373207468616e20737461727454696d6560281b604082015260600190565b6020808252600990820152680dad2dc407c40dac2f60bb1b604082015260600190565b600060408252600360408301526242757960e81b6060830152608060208301526108e1608083018461496b565b602080825260169082015275195e18d959591cc81c1d5c98da185cd9481b1a5b5a5d60521b604082015260600190565b60208082526010908201526f696e76616c696420666565207261746560801b604082015260600190565b600060408252600660408301526552656d6f766560d01b6060830152608060208301526108e1608083018461496b565b60208082526018908201527708ccaca7440caf0c6cacac8e640ead2dce862647040dac2f60431b604082015260600190565b60208082526010908201526f696e76616c6964206f66666572696e6760801b604082015260600190565b602080825260149082015273756e737570706f727465642063757272656e637960601b604082015260600190565b6020808252601390820152726f66666572696e672070726f63657373696e6760681b604082015260600190565b6020808252600e908201526d34b73b30b634b21039b7b63b32b960911b604082015260600190565b600060408252600560408301526427b33332b960d91b6060830152608060208301526108e1608083018461496b565b81516001600160801b039081168252602080840151821690830152604080840151909116908201526060808301516001600160401b0390811691830191909152608092830151169181019190915260a00190565b60006101a0820190506152068284516149db565b602083015161521860208401826149e4565b50604083015161522b60408401826149e4565b50606083015161523e60608401826149b6565b50608083015161525160808401826149ce565b5060a083015161526460a08401826149ce565b5060c083015161527760c08401826149ce565b5060e083015161528a60e08401826149ce565b506101008084015161529e82850182614958565b5050610120808401516152b382850182614958565b5050610140808401516152c882850182614958565b5050610160808401516152dd82850182614965565b5050610180808401516152f282850182614965565b505092915050565b6001600160801b0391909116815260200190565b6001600160801b03948516815292909316602083015263ffffffff9081166040830152909116606082015260800190565b6001600160801b03958616815293909416602084015263ffffffff918216604084015281166060830152909116608082015260a00190565b62ffffff91909116815260200190565b62ffffff9590951685526001600160a01b0393909316602085015260408401919091526001600160801b03908116606084015216608082015260a00190565b62ffffff8e16815263ffffffff8d811660208301528c1660408201526101a081016153f4606083018d6149b6565b6001600160801b038b16608083015261541060a083018b6149ce565b61541d60c083018a6149ce565b61542a60e08301896149ce565b615438610100830188614958565b615446610120830187614958565b615454610140830186614958565b615462610160830185614965565b614ad5610180830184614965565b90815260200190565b9182526001600160801b0316602082015260400190565b98895262ffffff97909716602089015263ffffffff9590951660408801526001600160a01b0393909316606087015260ff9190911660808601526001600160801b0390811660a086015290811660c085015260e0840191909152166101008201526101200190565b60ff9290921682526001600160801b0316602082015260400190565b813561551f81615618565b61552981836155d5565b50602082013561553881615618565b81546001600160801b031660809190911b6001600160801b03191617815560018101604083013561556881615618565b61557281836155d5565b5060608301356155818161563f565b8154600160801b600160c01b031916608091821b600160801b600160c01b031617808355908401356155b28161563f565b6001600160c01b039190911660c09190911b6001600160c01b0319161790555050565b80546001600160801b0319166001600160801b0392909216919091179055565b6001600160a01b03811681146133a657600080fd5b80151581146133a657600080fd5b6001600160801b03811681146133a657600080fd5b63ffffffff811681146133a657600080fd5b6001600160401b03811681146133a657600080fdfe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e64735265656e7472616e637947756172643a207265656e7472616e742063616c6c006475726174696f6e206d7573742067726561746572207468616e20696e74657276616c496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a2646970667358221220288267181ab87db14ba2d38d0d6a740f78041d66e19ce9ae575ae05a501312ef64736f6c63430007060033
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.