Source Code
Latest 25 from a total of 1,008 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Withdraw Mul | 297779878 | 376 days ago | IN | 0 ETH | 0.00000329 | ||||
| Withdraw Mul | 291803427 | 394 days ago | IN | 0 ETH | 0.00000151 | ||||
| Withdraw Mul | 288291465 | 404 days ago | IN | 0 ETH | 0.00000193 | ||||
| Withdraw Mul | 272022209 | 451 days ago | IN | 0 ETH | 0.0000024 | ||||
| Withdraw Mul | 271625141 | 453 days ago | IN | 0 ETH | 0.00000192 | ||||
| Withdraw Mul | 270974534 | 455 days ago | IN | 0 ETH | 0.00000256 | ||||
| Withdraw Mul | 269931559 | 458 days ago | IN | 0 ETH | 0.0000031 | ||||
| Withdraw Mul | 269693174 | 458 days ago | IN | 0 ETH | 0.00000174 | ||||
| Withdraw Mul | 265735778 | 470 days ago | IN | 0 ETH | 0.00000156 | ||||
| Withdraw Mul | 251467467 | 511 days ago | IN | 0 ETH | 0.00000094 | ||||
| Withdraw Mul | 235937042 | 556 days ago | IN | 0 ETH | 0.00000121 | ||||
| Withdraw Mul | 233934748 | 562 days ago | IN | 0 ETH | 0.00000179 | ||||
| Withdraw Mul | 233478221 | 564 days ago | IN | 0 ETH | 0.00000161 | ||||
| Withdraw Mul | 233425271 | 564 days ago | IN | 0 ETH | 0.00000435 | ||||
| Withdraw Mul | 233303664 | 564 days ago | IN | 0 ETH | 0.00000151 | ||||
| Withdraw Mul | 233057552 | 565 days ago | IN | 0 ETH | 0.00000209 | ||||
| Withdraw Mul | 230508028 | 572 days ago | IN | 0 ETH | 0.00000129 | ||||
| Withdraw Mul | 222097805 | 597 days ago | IN | 0 ETH | 0.00000112 | ||||
| Withdraw Mul | 222097739 | 597 days ago | IN | 0 ETH | 0.00000094 | ||||
| Withdraw Mul | 222097683 | 597 days ago | IN | 0 ETH | 0.00000094 | ||||
| Withdraw Mul | 222097619 | 597 days ago | IN | 0 ETH | 0.00000094 | ||||
| Withdraw Mul | 222097547 | 597 days ago | IN | 0 ETH | 0.00000094 | ||||
| Withdraw Mul | 222097470 | 597 days ago | IN | 0 ETH | 0.00000094 | ||||
| Withdraw Mul | 222097373 | 597 days ago | IN | 0 ETH | 0.00000112 | ||||
| Withdraw Mul | 221717399 | 598 days ago | IN | 0 ETH | 0.00000334 |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
RewardDistributor
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 200 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.17;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import "./libraries/TransferHelper.sol";
import "./common/Adminable.sol";
import "./common/ReentrancyGuard.sol";
import "./interface/IXOLE.sol";
import "./interface/IUniV2ClassPair.sol";
contract RewardDistributor is Adminable, ReentrancyGuard {
using TransferHelper for IERC20;
using TransferHelper for IUniV2ClassPair;
error InvalidAmount();
error InvalidTime();
error InvalidPenalty();
error InsufficientTransfersIn();
error NotStarted();
error Expired();
error NotExpired();
error AlreadyRecycled();
error AlreadyVested();
error IncorrectMerkleProof();
error ExceedMax(uint256 amount);
struct Epoch {
bytes32 merkleRoot;
uint256 total;
uint256 vested;
uint256 startTime; // vest start time
uint256 expireTime; // vest expire time
uint256 vestDuration; // vest duration, in seconds
uint16 penaltyBase; // exit penalty base percentage, 2000 => 20%
uint16 penaltyAdd; // exit penalty add percentage, 6000 => 60%
bool recycled;
}
struct Reward {
uint256 amount; // total amount to be vested
uint256 withdrawn; // withdrawn amount by the user
uint256 vestStartTime; // vest start time
}
uint256 internal constant PERCENT_DIVISOR = 10000;
uint256 private constant WEEK = 7 * 86400; // XOLE lock times are rounded by week
uint256 private constant MIN_DURATION = 7 * 86400; // 7 days
uint256 private constant MAX_DURATION = 4 * 365 * 86400; // 4 years
IERC20 public immutable oleToken;
IUniV2ClassPair public immutable pair;
address public immutable token1; // token1 of lp
address public immutable xole;
uint256 public epochIdx;
uint256 public minXOLELockDuration; // min XOLE lock duration in seconds when converting
uint256 public withdrawablePenalty; // the withdrawable penalty for admin
// mapping of epochId, user to reward info
mapping(uint256 => mapping(address => Reward)) public rewards;
// mapping of epochId to epoch info
mapping(uint256 => Epoch) public epochs;
constructor(address _oleToken, address _pair, address _token1, address _xole, uint256 _minXOLELockDuration) verifyDuration(_minXOLELockDuration){
oleToken = IERC20(_oleToken);
pair = IUniV2ClassPair(_pair);
token1 = _token1;
xole = _xole;
minXOLELockDuration = _minXOLELockDuration;
admin = payable(msg.sender);
}
event VestStarted(uint256 epochId, address account, uint256 balance, uint256 vestTime);
event Withdrawn(uint256 epochId, address account, uint256 amount, uint256 penalty);
event ConvertedToXOLE(uint256 epochId, address account, uint256 amount);
event EpochAdded(uint256 epochId, bytes32 merkleRoot, uint256 total, uint256 startTime, uint256 expireTime, uint256 vestDuration, uint16 penaltyBase, uint16 penaltyAdd);
event Recycled(uint256 epochId, uint256 recycledAmount);
event PenaltyWithdrawn(uint256 amount);
function vest(uint256 _epochId, uint256 _balance, bytes32[] calldata _merkleProof) external {
Epoch storage epoch = epochs[_epochId];
if (block.timestamp < epoch.startTime) revert NotStarted();
if (block.timestamp > epoch.expireTime) revert Expired();
if (_balance == 0 || _balance + epoch.vested > epoch.total) revert InvalidAmount();
Reward memory reward = rewards[_epochId][msg.sender];
if (reward.amount > 0) revert AlreadyVested();
if (!_verifyVest(msg.sender, epoch.merkleRoot, _balance, _merkleProof)) revert IncorrectMerkleProof();
epoch.vested += _balance;
rewards[_epochId][msg.sender] = Reward(_balance, 0, block.timestamp);
emit VestStarted(_epochId, msg.sender, _balance, block.timestamp);
}
function withdrawMul(uint256[] calldata _epochIds) external {
uint256 total;
for (uint256 i = 0; i < _epochIds.length; i++) {
total += _withdrawReward(_epochIds[i]);
}
oleToken.safeTransfer(msg.sender, total);
}
function withdraw(uint256 epochId) external {
uint256 withdrawing = _withdrawReward(epochId);
oleToken.safeTransfer(msg.sender, withdrawing);
}
function earlyExit(uint256 epochId) external {
Reward storage reward = rewards[epochId][msg.sender];
if (reward.amount == 0 || reward.amount == reward.withdrawn) revert InvalidAmount();
(uint256 withdrawable, uint256 penalty) = _earlyExitWithdrawable(reward, epochId);
reward.withdrawn = reward.amount;
withdrawablePenalty += penalty;
emit Withdrawn(epochId, msg.sender, withdrawable, penalty);
oleToken.safeTransfer(msg.sender, withdrawable);
}
/// @param token1MaxAmount, The token1 max supply amount when adding liquidity
/// @param unlockTime, The unlock time for the XOLE lock
function convertToNewXole(uint256 epochId, uint256 token1MaxAmount, uint256 unlockTime) external nonReentrant {
uint256 conversion = _convertOLE(epochId, msg.sender);
_convertToNewXole(msg.sender, conversion, token1MaxAmount, unlockTime);
}
function convertToNewXoleForOthers(uint256 epochId, address account, uint256 token1MaxAmount, uint256 unlockTime) external nonReentrant {
uint256 conversion = _convertOLE(epochId, msg.sender);
_convertToNewXole(account, conversion, token1MaxAmount, unlockTime);
}
function convertAndIncreaseXoleAmount(uint256 epochId, uint256 token1MaxAmount) external nonReentrant {
uint256 conversion = _convertOLE(epochId, msg.sender);
_convertAndIncreaseXoleAmount(msg.sender, conversion, token1MaxAmount);
}
function convertAndIncreaseXoleAmountForOthers(uint256 epochId, address account, uint256 token1MaxAmount) external nonReentrant {
uint256 conversion = _convertOLE(epochId, msg.sender);
_convertAndIncreaseXoleAmount(account, conversion, token1MaxAmount);
}
/*** View Functions ***/
function verifyVest(address account, uint256 _epochId, uint256 _balance, bytes32[] calldata _merkleProof) external view returns (bool valid){
return _verifyVest(account, epochs[_epochId].merkleRoot, _balance, _merkleProof);
}
function getWithdrawable(address account, uint256[] calldata _epochIds) external view returns (uint256[] memory results){
uint256 len = _epochIds.length;
results = new uint256[](len);
for (uint256 i = 0; i < len; i++) {
Reward memory reward = rewards[_epochIds[i]][account];
if (reward.amount == reward.withdrawn) {
results[i] = 0;
continue;
}
Epoch memory epoch = epochs[_epochIds[i]];
uint256 releaseAble = _releaseable(reward, epoch);
results[i] = releaseAble - reward.withdrawn;
}
}
function getEarlyExitWithdrawable(address account, uint256 _epochId) external view returns (uint256 amount, uint256 penalty){
Reward memory reward = rewards[_epochId][account];
if (reward.amount == reward.withdrawn) {
(amount, penalty) = (0, 0);
} else {
(amount, penalty) = _earlyExitWithdrawable(reward, _epochId);
}
}
/*** Admin Functions ***/
function newEpoch(
bytes32 merkleRoot,
uint256 total,
uint256 startTime,
uint256 expireTime,
uint256 vestDuration,
uint16 penaltyBase,
uint16 penaltyAdd)
external onlyAdminOrDeveloper verifyDuration(vestDuration) {
if (expireTime <= startTime || expireTime <= block.timestamp) revert InvalidTime();
if (total == 0 || penaltyBase + penaltyAdd >= PERCENT_DIVISOR) revert InvalidAmount();
uint256 received = oleToken.safeTransferFrom(msg.sender, address(this), total);
if(received != total) revert InsufficientTransfersIn();
uint256 epochId = ++epochIdx;
epochs[epochId] = Epoch(merkleRoot, total, 0, startTime, expireTime, vestDuration, penaltyBase, penaltyAdd, false);
emit EpochAdded(epochId, merkleRoot, total, startTime, expireTime, vestDuration, penaltyBase, penaltyAdd);
}
function recycle(uint256[] calldata _epochIds) external onlyAdmin {
uint256 total;
for (uint256 i = 0; i < _epochIds.length; i++) {
Epoch storage epoch = epochs[_epochIds[i]];
if (epoch.recycled) revert AlreadyRecycled();
if (block.timestamp <= epoch.expireTime) revert NotExpired();
uint256 recycleAmount = epoch.total - epoch.vested;
total += recycleAmount;
epoch.recycled = true;
emit Recycled(_epochIds[i], recycleAmount);
}
if (total == 0) revert InvalidAmount();
oleToken.safeTransfer(admin, total);
}
function withdrawPenalty() external onlyAdmin {
if (withdrawablePenalty == 0) revert InvalidAmount();
uint256 _withdrawablePenalty = withdrawablePenalty;
withdrawablePenalty = 0;
oleToken.safeTransfer(admin, _withdrawablePenalty);
emit PenaltyWithdrawn(_withdrawablePenalty);
}
function setMinXOLELockDuration(uint256 _minXOLELockDuration) external onlyAdmin verifyDuration(_minXOLELockDuration) {
minXOLELockDuration = _minXOLELockDuration;
}
/*** Internal Functions ***/
function _verifyVest(address account, bytes32 root, uint256 _balance, bytes32[] memory _merkleProof) internal pure returns (bool valid) {
bytes32 leaf = keccak256(abi.encodePacked(account, _balance));
return MerkleProof.verify(_merkleProof, root, leaf);
}
function _withdrawReward(uint256 epochId) internal returns (uint256){
Reward storage reward = rewards[epochId][msg.sender];
if (reward.amount == 0 || reward.amount == reward.withdrawn) revert InvalidAmount();
Epoch memory epoch = epochs[epochId];
uint256 withdrawing = _releaseable(reward, epoch) - reward.withdrawn;
if (withdrawing == 0) revert InvalidAmount();
reward.withdrawn += withdrawing;
emit Withdrawn(epochId, msg.sender, withdrawing, 0);
return withdrawing;
}
function _releaseable(Reward memory reward, Epoch memory epoch) internal view returns (uint256) {
uint256 endTime = reward.vestStartTime + epoch.vestDuration;
if (block.timestamp > endTime) {
return reward.amount;
} else {
return (block.timestamp - reward.vestStartTime) * reward.amount / epoch.vestDuration;
}
}
function _earlyExitWithdrawable(Reward memory reward, uint256 epochId) internal view returns (uint256 withdrawable, uint256 penalty) {
Epoch memory epoch = epochs[epochId];
uint256 releaseable = _releaseable(reward, epoch);
withdrawable = releaseable - reward.withdrawn;
// cal penalty
uint256 endTime = reward.vestStartTime + epoch.vestDuration;
uint256 penaltyFactor = (endTime - block.timestamp) * epoch.penaltyAdd / epoch.vestDuration + epoch.penaltyBase;
uint256 locked = reward.amount - releaseable;
penalty = locked * penaltyFactor / PERCENT_DIVISOR;
if (penalty >= locked) revert InvalidPenalty();
withdrawable += locked - penalty;
return (withdrawable, penalty);
}
function _convertOLE(uint256 epochId, address account) internal returns (uint256) {
Reward storage reward = rewards[epochId][account];
uint256 convertible = reward.amount - reward.withdrawn;
if (reward.amount == 0 || convertible == 0) revert InvalidAmount();
reward.withdrawn = reward.amount;
emit ConvertedToXOLE(epochId, account, convertible);
return convertible;
}
function _convertToNewXole(address account, uint256 oleAmount, uint256 token1MaxAmount, uint256 unlockTime) internal {
unlockTime = unlockTime / WEEK * WEEK;
verifyUnlockTime(unlockTime);
uint256 liquidity = formLp(oleAmount, token1MaxAmount);
pair.safeApprove(xole, liquidity);
IXOLE(xole).create_lock_for(account, liquidity, unlockTime);
}
function _convertAndIncreaseXoleAmount(address account, uint256 oleAmount, uint256 token1MaxAmount) internal {
(,uint256 lockTime) = IXOLE(xole).locked(account);
verifyUnlockTime(lockTime);
uint256 liquidity = formLp(oleAmount, token1MaxAmount);
pair.safeApprove(xole, liquidity);
IXOLE(xole).increase_amount_for(account, liquidity);
}
function formLp(uint256 oleAmount, uint256 token1MaxAmount) internal returns (uint256 liquidity){
(uint256 reserveA, uint256 reserveB) = getReserves(address(oleToken), token1);
uint256 amountBOptimal = oleAmount * reserveB / reserveA;
if (amountBOptimal > token1MaxAmount) revert ExceedMax(amountBOptimal);
IERC20(token1).safeTransferFrom(msg.sender, address(pair), amountBOptimal);
oleToken.safeTransfer(address(pair), oleAmount);
liquidity = pair.mint(address(this));
}
function getReserves(address tokenA, address tokenB) internal view returns (uint256 reserveA, uint256 reserveB) {
(uint256 reserve0, uint256 reserve1,) = pair.getReserves();
(address _token0,) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
(reserveA, reserveB) = tokenA == _token0 ? (reserve0, reserve1) : (reserve1, reserve0);
}
function verifyUnlockTime(uint256 _unlockTime) internal view {
if (_unlockTime < block.timestamp + minXOLELockDuration || _unlockTime > block.timestamp + MAX_DURATION) revert InvalidTime();
}
modifier verifyDuration(uint256 _duration) {
if (_duration < MIN_DURATION || _duration > MAX_DURATION) revert InvalidTime();
_;
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.17;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
/**
* @title TransferHelper
* @dev Wrappers around ERC20 operations that returns the value received by recipent and the actual allowance of approval.
* To use this library you can add a `using TransferHelper for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library TransferHelper {
function safeTransfer(
IERC20 _token,
address _to,
uint256 _amount
) internal returns (uint256 amountReceived) {
if (_amount > 0) {
bool success;
uint256 balanceBefore = _token.balanceOf(_to);
(success, ) = address(_token).call(abi.encodeWithSelector(_token.transfer.selector, _to, _amount));
require(success, "TF");
uint256 balanceAfter = _token.balanceOf(_to);
require(balanceAfter > balanceBefore, "TF");
amountReceived = balanceAfter - balanceBefore;
}
}
function safeTransferFrom(
IERC20 _token,
address _from,
address _to,
uint256 _amount
) internal returns (uint256 amountReceived) {
if (_amount > 0) {
bool success;
uint256 balanceBefore = _token.balanceOf(_to);
(success, ) = address(_token).call(abi.encodeWithSelector(_token.transferFrom.selector, _from, _to, _amount));
require(success, "TFF");
uint256 balanceAfter = _token.balanceOf(_to);
require(balanceAfter > balanceBefore, "TFF");
amountReceived = balanceAfter - balanceBefore;
}
}
function safeApprove(
IERC20 _token,
address _spender,
uint256 _amount
) internal returns (uint256) {
bool success;
if (_token.allowance(address(this), _spender) != 0) {
(success, ) = address(_token).call(abi.encodeWithSelector(_token.approve.selector, _spender, 0));
require(success, "AF");
}
(success, ) = address(_token).call(abi.encodeWithSelector(_token.approve.selector, _spender, _amount));
require(success, "AF");
return _token.allowance(address(this), _spender);
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.17;
interface IXOLE{
function create_lock_for(address to, uint256 _value, uint256 _unlock_time) external;
function increase_amount_for(address to, uint256 _value) external;
function balanceOf(address addr) external view returns (uint256);
function locked(address addr) external view returns (uint256 amount, uint256 lockTime);
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.17;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IUniV2ClassPair is IERC20{
function mint(address to) external returns (uint liquidity);
function token0() external view returns (address);
function token1() external view returns (address);
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.17;
contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
check();
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
function check() private view {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.17;
abstract contract Adminable {
address payable public admin;
address payable public pendingAdmin;
address payable public developer;
event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);
event NewAdmin(address oldAdmin, address newAdmin);
constructor() {
developer = payable(msg.sender);
}
modifier onlyAdmin() {
checkAdmin();
_;
}
modifier onlyAdminOrDeveloper() {
require(msg.sender == admin || msg.sender == developer, "Only admin or dev");
_;
}
function setPendingAdmin(address payable newPendingAdmin) external virtual onlyAdmin {
// Save current value, if any, for inclusion in log
address oldPendingAdmin = pendingAdmin;
// Store pendingAdmin with value newPendingAdmin
pendingAdmin = newPendingAdmin;
// Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)
emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);
}
function acceptAdmin() external virtual {
require(msg.sender == pendingAdmin, "Only pendingAdmin");
// Save current values for inclusion in log
address oldAdmin = admin;
address oldPendingAdmin = pendingAdmin;
// Store admin with value pendingAdmin
admin = pendingAdmin;
// Clear the pending value
pendingAdmin = payable(0);
emit NewAdmin(oldAdmin, admin);
emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);
}
function checkAdmin() private view {
require(msg.sender == admin, "caller must be admin");
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.2) (utils/cryptography/MerkleProof.sol)
pragma solidity ^0.8.0;
/**
* @dev These functions deal with verification of Merkle Tree proofs.
*
* The tree and the proofs can be generated using our
* https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
* You will find a quickstart guide in the readme.
*
* WARNING: You should avoid using leaf values that are 64 bytes long prior to
* hashing, or use a hash function other than keccak256 for hashing leaves.
* This is because the concatenation of a sorted pair of internal nodes in
* the merkle tree could be reinterpreted as a leaf value.
* OpenZeppelin's JavaScript library generates merkle trees that are safe
* against this attack out of the box.
*/
library MerkleProof {
/**
* @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
* defined by `root`. For this, a `proof` must be provided, containing
* sibling hashes on the branch from the leaf to the root of the tree. Each
* pair of leaves and each pair of pre-images are assumed to be sorted.
*/
function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
return processProof(proof, leaf) == root;
}
/**
* @dev Calldata version of {verify}
*
* _Available since v4.7._
*/
function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
return processProofCalldata(proof, leaf) == root;
}
/**
* @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
* from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
* hash matches the root of the tree. When processing the proof, the pairs
* of leafs & pre-images are assumed to be sorted.
*
* _Available since v4.4._
*/
function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = _hashPair(computedHash, proof[i]);
}
return computedHash;
}
/**
* @dev Calldata version of {processProof}
*
* _Available since v4.7._
*/
function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = _hashPair(computedHash, proof[i]);
}
return computedHash;
}
/**
* @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by
* `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
*
* CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
*
* _Available since v4.7._
*/
function multiProofVerify(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProof(proof, proofFlags, leaves) == root;
}
/**
* @dev Calldata version of {multiProofVerify}
*
* CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
*
* _Available since v4.7._
*/
function multiProofVerifyCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProofCalldata(proof, proofFlags, leaves) == root;
}
/**
* @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
* proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
* leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
* respectively.
*
* CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
* is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
* tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
*
* _Available since v4.7._
*/
function processMultiProof(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
// This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
// consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
// `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
// the merkle tree.
uint256 leavesLen = leaves.length;
uint256 proofLen = proof.length;
uint256 totalHashes = proofFlags.length;
// Check proof validity.
require(leavesLen + proofLen - 1 == totalHashes, "MerkleProof: invalid multiproof");
// The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
// `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
bytes32[] memory hashes = new bytes32[](totalHashes);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
// At each step, we compute the next hash using two values:
// - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
// get the next hash.
// - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
// `proof` array.
for (uint256 i = 0; i < totalHashes; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i]
? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
: proof[proofPos++];
hashes[i] = _hashPair(a, b);
}
if (totalHashes > 0) {
require(proofPos == proofLen, "MerkleProof: invalid multiproof");
unchecked {
return hashes[totalHashes - 1];
}
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
/**
* @dev Calldata version of {processMultiProof}.
*
* CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
*
* _Available since v4.7._
*/
function processMultiProofCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
// This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
// consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
// `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
// the merkle tree.
uint256 leavesLen = leaves.length;
uint256 proofLen = proof.length;
uint256 totalHashes = proofFlags.length;
// Check proof validity.
require(leavesLen + proofLen - 1 == totalHashes, "MerkleProof: invalid multiproof");
// The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
// `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
bytes32[] memory hashes = new bytes32[](totalHashes);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
// At each step, we compute the next hash using two values:
// - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
// get the next hash.
// - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
// `proof` array.
for (uint256 i = 0; i < totalHashes; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i]
? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
: proof[proofPos++];
hashes[i] = _hashPair(a, b);
}
if (totalHashes > 0) {
require(proofPos == proofLen, "MerkleProof: invalid multiproof");
unchecked {
return hashes[totalHashes - 1];
}
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
}
function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, a)
mstore(0x20, b)
value := keccak256(0x00, 0x40)
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}{
"remappings": [],
"optimizer": {
"enabled": true,
"runs": 200
},
"evmVersion": "london",
"libraries": {},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_oleToken","type":"address"},{"internalType":"address","name":"_pair","type":"address"},{"internalType":"address","name":"_token1","type":"address"},{"internalType":"address","name":"_xole","type":"address"},{"internalType":"uint256","name":"_minXOLELockDuration","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyRecycled","type":"error"},{"inputs":[],"name":"AlreadyVested","type":"error"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ExceedMax","type":"error"},{"inputs":[],"name":"Expired","type":"error"},{"inputs":[],"name":"IncorrectMerkleProof","type":"error"},{"inputs":[],"name":"InsufficientTransfersIn","type":"error"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidPenalty","type":"error"},{"inputs":[],"name":"InvalidTime","type":"error"},{"inputs":[],"name":"NotExpired","type":"error"},{"inputs":[],"name":"NotStarted","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"epochId","type":"uint256"},{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ConvertedToXOLE","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"epochId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"total","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"expireTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"vestDuration","type":"uint256"},{"indexed":false,"internalType":"uint16","name":"penaltyBase","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"penaltyAdd","type":"uint16"}],"name":"EpochAdded","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":"uint256","name":"amount","type":"uint256"}],"name":"PenaltyWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"epochId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"recycledAmount","type":"uint256"}],"name":"Recycled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"epochId","type":"uint256"},{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"vestTime","type":"uint256"}],"name":"VestStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"epochId","type":"uint256"},{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"penalty","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[],"name":"acceptAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epochId","type":"uint256"},{"internalType":"uint256","name":"token1MaxAmount","type":"uint256"}],"name":"convertAndIncreaseXoleAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"epochId","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"token1MaxAmount","type":"uint256"}],"name":"convertAndIncreaseXoleAmountForOthers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"epochId","type":"uint256"},{"internalType":"uint256","name":"token1MaxAmount","type":"uint256"},{"internalType":"uint256","name":"unlockTime","type":"uint256"}],"name":"convertToNewXole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"epochId","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"token1MaxAmount","type":"uint256"},{"internalType":"uint256","name":"unlockTime","type":"uint256"}],"name":"convertToNewXoleForOthers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"developer","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epochId","type":"uint256"}],"name":"earlyExit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"epochIdx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"epochs","outputs":[{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"vested","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"expireTime","type":"uint256"},{"internalType":"uint256","name":"vestDuration","type":"uint256"},{"internalType":"uint16","name":"penaltyBase","type":"uint16"},{"internalType":"uint16","name":"penaltyAdd","type":"uint16"},{"internalType":"bool","name":"recycled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"_epochId","type":"uint256"}],"name":"getEarlyExitWithdrawable","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"penalty","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256[]","name":"_epochIds","type":"uint256[]"}],"name":"getWithdrawable","outputs":[{"internalType":"uint256[]","name":"results","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minXOLELockDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"expireTime","type":"uint256"},{"internalType":"uint256","name":"vestDuration","type":"uint256"},{"internalType":"uint16","name":"penaltyBase","type":"uint16"},{"internalType":"uint16","name":"penaltyAdd","type":"uint16"}],"name":"newEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"oleToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pair","outputs":[{"internalType":"contract IUniV2ClassPair","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingAdmin","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_epochIds","type":"uint256[]"}],"name":"recycle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"rewards","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"withdrawn","type":"uint256"},{"internalType":"uint256","name":"vestStartTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minXOLELockDuration","type":"uint256"}],"name":"setMinXOLELockDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"newPendingAdmin","type":"address"}],"name":"setPendingAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"_epochId","type":"uint256"},{"internalType":"uint256","name":"_balance","type":"uint256"},{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"}],"name":"verifyVest","outputs":[{"internalType":"bool","name":"valid","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_epochId","type":"uint256"},{"internalType":"uint256","name":"_balance","type":"uint256"},{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"}],"name":"vest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"epochId","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_epochIds","type":"uint256[]"}],"name":"withdrawMul","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawPenalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawablePenalty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"xole","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
6101006040523480156200001257600080fd5b5060405162002d1e38038062002d1e8339810160408190526200003591620000da565b600280546001600160a01b0319163317905560016003558062093a80811080620000625750630784ce0081115b1562000081576040516337bf561360e11b815260040160405180910390fd5b506001600160a01b0394851660805292841660a05290831660c05290911660e052600555600080546001600160a01b0319163317905562000141565b80516001600160a01b0381168114620000d557600080fd5b919050565b600080600080600060a08688031215620000f357600080fd5b620000fe86620000bd565b94506200010e60208701620000bd565b93506200011e60408701620000bd565b92506200012e60608701620000bd565b9150608086015190509295509295909350565b60805160a05160c05160e051612b106200020e600039600081816101fe01528181611a8d01528181611b4201528181611b8e01528181611cb50152611d080152600081816104cf01528181611fce015261204001526000818161036001528181611b2001528181611c9301528181612063015281816120b8015281816120f301526124550152600081816102e9015281816106e8015281816109d401528181610e5001528181610f78015281816110b20152818161132e01528181611fad01526120960152612b106000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c8063664c374111610104578063c72a8c95116100a2578063d041d59411610071578063d041d594146104a7578063d21220a7146104ca578063f2db11af146104f1578063f851a4401461054657600080fd5b8063c72a8c9514610465578063c812be311461046e578063ca4b208b14610481578063ce0e22b71461049457600080fd5b8063b8af3d3e116100de578063b8af3d3e14610382578063b9d8ce8914610395578063bd3bc19b1461039e578063c6b61e4c146103b157600080fd5b8063664c374114610331578063768d79f314610348578063a8aa1b311461035b57600080fd5b80632e1a7d4d116101715780634dd18bf51161014b5780634dd18bf5146102d157806353e083a8146102e457806356b7d7511461030b578063607bebe31461031e57600080fd5b80632e1a7d4d1461028b578063361ce2451461029e57806346f10881146102b157600080fd5b80631aef5e0d116101ad5780631aef5e0d146101f95780631cea75b61461023d57806326561b9214610250578063267822471461027857600080fd5b806304ca99d2146101d45780630e18b681146101e95780631a1ce2fc146101f1575b600080fd5b6101e76101e2366004612571565b610559565b005b6101e761059a565b6101e76106a3565b6102207f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6101e761024b3660046125cf565b610748565b61026361025e366004612637565b610947565b60408051928352602083019190915201610234565b600154610220906001600160a01b031681565b6101e7610299366004612571565b6109ba565b6101e76102ac366004612663565b610a00565b6102c46102bf36600461269b565b610a31565b60405161023491906126f0565b6101e76102df366004612734565b610c23565b6102207f000000000000000000000000000000000000000000000000000000000000000081565b6101e7610319366004612751565b610c85565b6101e761032c366004612773565b610cb5565b61033a60045481565b604051908152602001610234565b6101e761035636600461279f565b610cdc565b6102207f000000000000000000000000000000000000000000000000000000000000000081565b6101e7610390366004612571565b610e7f565b61033a60065481565b6101e76103ac3660046127f8565b610fa6565b6104186103bf366004612571565b6008602052600090815260409020805460018201546002830154600384015460048501546005860154600690960154949593949293919290919061ffff8082169162010000810490911690640100000000900460ff1689565b60408051998a5260208a0198909852968801959095526060870193909352608086019190915260a085015261ffff90811660c08501521660e0830152151561010082015261012001610234565b61033a60055481565b6101e761047c36600461285b565b6112a2565b600254610220906001600160a01b031681565b6101e76104a236600461279f565b6112d5565b6104ba6104b5366004612898565b611355565b6040519015158152602001610234565b6102207f000000000000000000000000000000000000000000000000000000000000000081565b61052b6104ff366004612902565b600760209081526000928352604080842090915290825290208054600182015460029092015490919083565b60408051938452602084019290925290820152606001610234565b600054610220906001600160a01b031681565b6105616113ac565b8062093a808110806105765750630784ce0081115b15610594576040516337bf561360e11b815260040160405180910390fd5b50600555565b6001546001600160a01b031633146105ed5760405162461bcd60e51b815260206004820152601160248201527027b7363c903832b73234b733a0b236b4b760791b60448201526064015b60405180910390fd5b60008054600180546001600160a01b038082166001600160a01b031980861682179096559490911690915560408051919092168082526020820184905292917ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc910160405180910390a1600154604080516001600160a01b03808516825290921660208301527fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a991015b60405180910390a15050565b6106ab6113ac565b6006546000036106ce5760405163162908e360e11b815260040160405180910390fd5b600680546000918290559054610711906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169116836113ff565b506040518181527f6282ca7732d1b80bfd787b44224abfc15a64c17fbef2bfc95c5fc06b30a06bee9060200160405180910390a150565b6000848152600860205260409020600381015442101561077b57604051636f312cbd60e01b815260040160405180910390fd5b80600401544211156107a057604051630407b05b60e31b815260040160405180910390fd5b8315806107be5750600181015460028201546107bc9086612948565b115b156107dc5760405163162908e360e11b815260040160405180910390fd5b600085815260076020908152604080832033845282529182902082516060810184528154808252600183015493820193909352600290910154928101929092521561083a5760405163ef89654560e01b815260040160405180910390fd5b61087d3383600001548787878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061160592505050565b61089a57604051635d2f8a0560e01b815260040160405180910390fd5b848260020160008282546108ae9190612948565b9091555050604080516060808201835287825260006020808401828152428587018181528d85526007845287852033808752908552948890209651875591516001870155905160029095019490945584518b8152908101919091529283018890528201527fc69c7dfb3e15d339bfed989be99d97589fc7bb295b3ab2db82829106001b9e2d9060800160405180910390a1505050505050565b60008181526007602090815260408083206001600160a01b0386168452825280832081516060810183528154808252600183015494820185905260029092015492810192909252839290036109a257600092508291506109b2565b6109ac818561165f565b90935091505b509250929050565b60006109c5826117cf565b90506109fb6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633836113ff565b505050565b610a0861195e565b60026003556000610a1984336119b0565b9050610a26838284611a6b565b505060016003555050565b6060818067ffffffffffffffff811115610a4d57610a4d61295b565b604051908082528060200260200182016040528015610a76578160200160208202803683370190505b50915060005b81811015610c1a57600060076000878785818110610a9c57610a9c612971565b6020908102929092013583525081810192909252604090810160009081206001600160a01b038b16825283528190208151606081018352815480825260018301549482018590526002909201549281019290925290925003610b1e576000848381518110610b0c57610b0c612971565b60200260200101818152505050610c08565b600060086000888886818110610b3657610b36612971565b602090810292909201358352508181019290925260409081016000908120825161012081018452815481526001820154948101949094526002810154928401929092526003820154606084015260048201546080840152600582015460a084015260069091015461ffff80821660c08501526201000082041660e0840152640100000000900460ff161515610100830152909150610bd48383611bf2565b9050826020015181610be69190612987565b868581518110610bf857610bf8612971565b6020026020010181815250505050505b80610c128161299a565b915050610a7c565b50509392505050565b610c2b6113ac565b600180546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a99101610697565b610c8d61195e565b60026003556000610c9e83336119b0565b9050610cab338284611a6b565b5050600160035550565b610cbd61195e565b60026003556000610cce84336119b0565b9050610a2633828585611c55565b610ce46113ac565b6000805b82811015610e1d57600060086000868685818110610d0857610d08612971565b90506020020135815260200190815260200160002090508060060160049054906101000a900460ff1615610d4f576040516336b5f2f760e11b815260040160405180910390fd5b80600401544211610d735760405163d0404f8560e01b815260040160405180910390fd5b600081600201548260010154610d899190612987565b9050610d958185612948565b60068301805464ff00000000191664010000000017905593507fadb56f2e8c8dd63466fb638690ea115eeb4f568e6e732d67200d1646b15ece75868685818110610de157610de1612971565b9050602002013582604051610e00929190918252602082015260400190565b60405180910390a150508080610e159061299a565b915050610ce8565b5080600003610e3f5760405163162908e360e11b815260040160405180910390fd5b600054610e79906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169116836113ff565b50505050565b6000818152600760209081526040808320338452909152902080541580610eaa575060018101548154145b15610ec85760405163162908e360e11b815260040160405180910390fd5b600080610efe8360405180606001604052908160008201548152602001600182015481526020016002820154815250508561165f565b84546001860155600680549294509092508291600090610f1f908490612948565b909155505060408051858152336020820152908101839052606081018290527f1c84cc0f96161bdafea718a9094dd21c21d1fb2f9ca2ebb9bd4e39918efbaace9060800160405180910390a1610f9f6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633846113ff565b5050505050565b6000546001600160a01b0316331480610fc957506002546001600160a01b031633145b6110095760405162461bcd60e51b815260206004820152601160248201527027b7363c9030b236b4b71037b9103232bb60791b60448201526064016105e4565b8262093a8081108061101e5750630784ce0081115b1561103c576040516337bf561360e11b815260040160405180910390fd5b858511158061104b5750428511155b15611069576040516337bf561360e11b815260040160405180910390fd5b861580611085575061271061107e83856129b3565b61ffff1610155b156110a35760405163162908e360e11b815260040160405180910390fd5b60006110da6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308b611d37565b90508781146110fb576040516276f4ff60e41b815260040160405180910390fd5b600060046000815461110c9061299a565b91905081905590506040518061012001604052808b81526020018a8152602001600081526020018981526020018881526020018781526020018661ffff1681526020018561ffff1681526020016000151581525060086000838152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c08201518160060160006101000a81548161ffff021916908361ffff16021790555060e08201518160060160026101000a81548161ffff021916908361ffff1602179055506101008201518160060160046101000a81548160ff0219169083151502179055509050507f9a5ab6171e45c59f905bba9a5e5d913c4457dfb38e5b695f717aa33b6b6c1362818b8b8b8b8b8b8b60405161128e989796959493929190978852602088019690965260408701949094526060860192909252608085015260a084015261ffff90811660c08401521660e08201526101000190565b60405180910390a150505050505050505050565b6112aa61195e565b600260035560006112bb85336119b0565b90506112c984828585611c55565b50506001600355505050565b6000805b82811015611320576113028484838181106112f6576112f6612971565b905060200201356117cf565b61130c9083612948565b9150806113188161299a565b9150506112d9565b50610e796001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633836113ff565b600084815260086020908152604080832054815185840281810185019093528581526113a2938a938992918991899182919085019084908082843760009201919091525061160592505050565b9695505050505050565b6000546001600160a01b031633146113fd5760405162461bcd60e51b815260206004820152601460248201527331b0b63632b91036bab9ba1031329030b236b4b760611b60448201526064016105e4565b565b600081156115fe576040516370a0823160e01b81526001600160a01b03848116600483015260009182918716906370a0823190602401602060405180830381865afa158015611452573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147691906129ce565b604080516001600160a01b038881166024830152604480830189905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151929350908816916114d091906129e7565b6000604051808303816000865af19150503d806000811461150d576040519150601f19603f3d011682016040523d82523d6000602084013e611512565b606091505b5050809250508161154a5760405162461bcd60e51b81526020600482015260026024820152612a2360f11b60448201526064016105e4565b6040516370a0823160e01b81526001600160a01b038681166004830152600091908816906370a0823190602401602060405180830381865afa158015611594573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b891906129ce565b90508181116115ee5760405162461bcd60e51b81526020600482015260026024820152612a2360f11b60448201526064016105e4565b6115f88282612987565b93505050505b9392505050565b6040516bffffffffffffffffffffffff19606086901b166020820152603481018390526000908190605401604051602081830303815290604052805190602001209050611653838683611f46565b9150505b949350505050565b6000818152600860209081526040808320815161012081018352815481526001820154938101939093526002810154918301919091526003810154606083015260048101546080830152600581015460a08301526006015461ffff80821660c08401526201000082041660e0830152640100000000900460ff1615156101008201528190816116ee8683611bf2565b90508560200151816117009190612987565b935060008260a0015187604001516117189190612948565b905060008360c0015161ffff168460a001518560e0015161ffff16428561173f9190612987565b6117499190612a16565b6117539190612a2d565b61175d9190612948565b905060008389600001516117719190612987565b90506127106117808383612a16565b61178a9190612a2d565b95508086106117ac5760405163458eae5b60e01b815260040160405180910390fd5b6117b68682612987565b6117c09088612948565b965050505050505b9250929050565b60008181526007602090815260408083203384529091528120805415806117fa575060018101548154145b156118185760405163162908e360e11b815260040160405180910390fd5b6000838152600860209081526040808320815161012081018352815481526001808301548286015260028084015483860152600384015460608085019190915260048501546080850152600585015460a085015260069094015461ffff80821660c08601526201000082041660e0850152640100000000900460ff16151561010084015290870154845193840185528754845294830185905286015492820192909252909291906118c99084611bf2565b6118d39190612987565b9050806000036118f65760405163162908e360e11b815260040160405180910390fd5b8083600101600082825461190a9190612948565b909155505060408051868152336020820152908101829052600060608201527f1c84cc0f96161bdafea718a9094dd21c21d1fb2f9ca2ebb9bd4e39918efbaace9060800160405180910390a1949350505050565b6002600354036113fd5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016105e4565b60008281526007602090815260408083206001600160a01b038516845290915281206001810154815483916119e491612987565b825490915015806119f3575080155b15611a115760405163162908e360e11b815260040160405180910390fd5b81546001830155604080518681526001600160a01b03861660208201529081018290527f0235b6790a877095b8878d0a0e0af7c5442875c0ac9f901c07584ff6f71d9d6d9060600160405180910390a19150505b92915050565b60405163cbf9fe5f60e01b81526001600160a01b0384811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063cbf9fe5f906024016040805180830381865afa158015611ad5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af99190612a4f565b915050611b0581611f5c565b6000611b118484611fa3565b9050611b676001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000083612168565b5060405163743241bb60e11b81526001600160a01b038681166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063e8648376906044015b600060405180830381600087803b158015611bd357600080fd5b505af1158015611be7573d6000803e3d6000fd5b505050505050505050565b6000808260a001518460400151611c099190612948565b905080421115611c1c5750508151611a65565b60a083015184516040860151611c329042612987565b611c3c9190612a16565b611c469190612a2d565b915050611a65565b5092915050565b62093a80611c638183612a2d565b611c6d9190612a16565b9050611c7881611f5c565b6000611c848484611fa3565b9050611cda6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000083612168565b50604051633e173b2960e01b81526001600160a01b03868116600483015260248201839052604482018490527f00000000000000000000000000000000000000000000000000000000000000001690633e173b2990606401611bb9565b60008115611657576040516370a0823160e01b81526001600160a01b03848116600483015260009182918816906370a0823190602401602060405180830381865afa158015611d8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dae91906129ce565b604080516001600160a01b0389811660248301528881166044830152606480830189905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b179052915192935090891691611e1091906129e7565b6000604051808303816000865af19150503d8060008114611e4d576040519150601f19603f3d011682016040523d82523d6000602084013e611e52565b606091505b50508092505081611e8b5760405162461bcd60e51b81526020600482015260036024820152622a232360e91b60448201526064016105e4565b6040516370a0823160e01b81526001600160a01b038681166004830152600091908916906370a0823190602401602060405180830381865afa158015611ed5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef991906129ce565b9050818111611f305760405162461bcd60e51b81526020600482015260036024820152622a232360e91b60448201526064016105e4565b611f3a8282612987565b98975050505050505050565b600082611f538584612400565b14949350505050565b600554611f699042612948565b811080611f825750611f7f630784ce0042612948565b81115b15611fa0576040516337bf561360e11b815260040160405180910390fd5b50565b6000806000611ff27f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000061244d565b90925090506000826120048388612a16565b61200e9190612a2d565b9050848111156120335760405162d3c55f60e61b8152600481018290526024016105e4565b6120886001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016337f000000000000000000000000000000000000000000000000000000000000000084611d37565b506120dd6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000886113ff565b506040516335313c2160e11b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636a627842906024016020604051808303816000875af1158015612144573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a291906129ce565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091829186169063dd62ed3e90604401602060405180830381865afa1580156121b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121dd91906129ce565b156122b657604080516001600160a01b038681166024830152600060448084019190915283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b17905291519187169161223c91906129e7565b6000604051808303816000865af19150503d8060008114612279576040519150601f19603f3d011682016040523d82523d6000602084013e61227e565b606091505b505080915050806122b65760405162461bcd60e51b815260206004820152600260248201526120a360f11b60448201526064016105e4565b604080516001600160a01b038681166024830152604480830187905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b17905291519187169161230d91906129e7565b6000604051808303816000865af19150503d806000811461234a576040519150601f19603f3d011682016040523d82523d6000602084013e61234f565b606091505b505080915050806123875760405162461bcd60e51b815260206004820152600260248201526120a360f11b60448201526064016105e4565b604051636eb1769f60e11b81523060048201526001600160a01b03858116602483015286169063dd62ed3e90604401602060405180830381865afa1580156123d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123f791906129ce565b95945050505050565b600081815b8451811015612445576124318286838151811061242457612424612971565b6020026020010151612545565b91508061243d8161299a565b915050612405565b509392505050565b6000806000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156124b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124d59190612a8a565b506001600160701b031691506001600160701b031691506000856001600160a01b0316876001600160a01b03161061250e578587612511565b86865b509050806001600160a01b0316876001600160a01b031614612534578183612537565b82825b909890975095505050505050565b60008183106125615760008281526020849052604090206115fe565b5060009182526020526040902090565b60006020828403121561258357600080fd5b5035919050565b60008083601f84011261259c57600080fd5b50813567ffffffffffffffff8111156125b457600080fd5b6020830191508360208260051b85010111156117c857600080fd5b600080600080606085870312156125e557600080fd5b8435935060208501359250604085013567ffffffffffffffff81111561260a57600080fd5b6126168782880161258a565b95989497509550505050565b6001600160a01b0381168114611fa057600080fd5b6000806040838503121561264a57600080fd5b823561265581612622565b946020939093013593505050565b60008060006060848603121561267857600080fd5b83359250602084013561268a81612622565b929592945050506040919091013590565b6000806000604084860312156126b057600080fd5b83356126bb81612622565b9250602084013567ffffffffffffffff8111156126d757600080fd5b6126e38682870161258a565b9497909650939450505050565b6020808252825182820181905260009190848201906040850190845b818110156127285783518352928401929184019160010161270c565b50909695505050505050565b60006020828403121561274657600080fd5b81356115fe81612622565b6000806040838503121561276457600080fd5b50508035926020909101359150565b60008060006060848603121561278857600080fd5b505081359360208301359350604090920135919050565b600080602083850312156127b257600080fd5b823567ffffffffffffffff8111156127c957600080fd5b6127d58582860161258a565b90969095509350505050565b803561ffff811681146127f357600080fd5b919050565b600080600080600080600060e0888a03121561281357600080fd5b873596506020880135955060408801359450606088013593506080880135925061283f60a089016127e1565b915061284d60c089016127e1565b905092959891949750929550565b6000806000806080858703121561287157600080fd5b84359350602085013561288381612622565b93969395505050506040820135916060013590565b6000806000806000608086880312156128b057600080fd5b85356128bb81612622565b94506020860135935060408601359250606086013567ffffffffffffffff8111156128e557600080fd5b6128f18882890161258a565b969995985093965092949392505050565b6000806040838503121561291557600080fd5b82359150602083013561292781612622565b809150509250929050565b634e487b7160e01b600052601160045260246000fd5b80820180821115611a6557611a65612932565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b81810381811115611a6557611a65612932565b6000600182016129ac576129ac612932565b5060010190565b61ffff818116838216019080821115611c4e57611c4e612932565b6000602082840312156129e057600080fd5b5051919050565b6000825160005b81811015612a0857602081860181015185830152016129ee565b506000920191825250919050565b8082028115828204841417611a6557611a65612932565b600082612a4a57634e487b7160e01b600052601260045260246000fd5b500490565b60008060408385031215612a6257600080fd5b505080516020909101519092909150565b80516001600160701b03811681146127f357600080fd5b600080600060608486031215612a9f57600080fd5b612aa884612a73565b9250612ab660208501612a73565b9150604084015163ffffffff81168114612acf57600080fd5b80915050925092509256fea2646970667358221220e8750343cb1fe1e65198b0a3e5bac082b2a8897d600a33e5ce0f7e8108ab210364736f6c634300081100330000000000000000000000007be5dd337cc6ce3e474f64e2a92a566445290864000000000000000000000000fdb2c36b73e18871d9208cc508c911a1bffcfb8e000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e58310000000000000000000000001c59529ba394427d9a18a3ef6b8ca38906b8e2db000000000000000000000000000000000000000000000000000000000024ea00
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101cf5760003560e01c8063664c374111610104578063c72a8c95116100a2578063d041d59411610071578063d041d594146104a7578063d21220a7146104ca578063f2db11af146104f1578063f851a4401461054657600080fd5b8063c72a8c9514610465578063c812be311461046e578063ca4b208b14610481578063ce0e22b71461049457600080fd5b8063b8af3d3e116100de578063b8af3d3e14610382578063b9d8ce8914610395578063bd3bc19b1461039e578063c6b61e4c146103b157600080fd5b8063664c374114610331578063768d79f314610348578063a8aa1b311461035b57600080fd5b80632e1a7d4d116101715780634dd18bf51161014b5780634dd18bf5146102d157806353e083a8146102e457806356b7d7511461030b578063607bebe31461031e57600080fd5b80632e1a7d4d1461028b578063361ce2451461029e57806346f10881146102b157600080fd5b80631aef5e0d116101ad5780631aef5e0d146101f95780631cea75b61461023d57806326561b9214610250578063267822471461027857600080fd5b806304ca99d2146101d45780630e18b681146101e95780631a1ce2fc146101f1575b600080fd5b6101e76101e2366004612571565b610559565b005b6101e761059a565b6101e76106a3565b6102207f0000000000000000000000001c59529ba394427d9a18a3ef6b8ca38906b8e2db81565b6040516001600160a01b0390911681526020015b60405180910390f35b6101e761024b3660046125cf565b610748565b61026361025e366004612637565b610947565b60408051928352602083019190915201610234565b600154610220906001600160a01b031681565b6101e7610299366004612571565b6109ba565b6101e76102ac366004612663565b610a00565b6102c46102bf36600461269b565b610a31565b60405161023491906126f0565b6101e76102df366004612734565b610c23565b6102207f0000000000000000000000007be5dd337cc6ce3e474f64e2a92a56644529086481565b6101e7610319366004612751565b610c85565b6101e761032c366004612773565b610cb5565b61033a60045481565b604051908152602001610234565b6101e761035636600461279f565b610cdc565b6102207f000000000000000000000000fdb2c36b73e18871d9208cc508c911a1bffcfb8e81565b6101e7610390366004612571565b610e7f565b61033a60065481565b6101e76103ac3660046127f8565b610fa6565b6104186103bf366004612571565b6008602052600090815260409020805460018201546002830154600384015460048501546005860154600690960154949593949293919290919061ffff8082169162010000810490911690640100000000900460ff1689565b60408051998a5260208a0198909852968801959095526060870193909352608086019190915260a085015261ffff90811660c08501521660e0830152151561010082015261012001610234565b61033a60055481565b6101e761047c36600461285b565b6112a2565b600254610220906001600160a01b031681565b6101e76104a236600461279f565b6112d5565b6104ba6104b5366004612898565b611355565b6040519015158152602001610234565b6102207f000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e583181565b61052b6104ff366004612902565b600760209081526000928352604080842090915290825290208054600182015460029092015490919083565b60408051938452602084019290925290820152606001610234565b600054610220906001600160a01b031681565b6105616113ac565b8062093a808110806105765750630784ce0081115b15610594576040516337bf561360e11b815260040160405180910390fd5b50600555565b6001546001600160a01b031633146105ed5760405162461bcd60e51b815260206004820152601160248201527027b7363c903832b73234b733a0b236b4b760791b60448201526064015b60405180910390fd5b60008054600180546001600160a01b038082166001600160a01b031980861682179096559490911690915560408051919092168082526020820184905292917ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc910160405180910390a1600154604080516001600160a01b03808516825290921660208301527fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a991015b60405180910390a15050565b6106ab6113ac565b6006546000036106ce5760405163162908e360e11b815260040160405180910390fd5b600680546000918290559054610711906001600160a01b037f0000000000000000000000007be5dd337cc6ce3e474f64e2a92a56644529086481169116836113ff565b506040518181527f6282ca7732d1b80bfd787b44224abfc15a64c17fbef2bfc95c5fc06b30a06bee9060200160405180910390a150565b6000848152600860205260409020600381015442101561077b57604051636f312cbd60e01b815260040160405180910390fd5b80600401544211156107a057604051630407b05b60e31b815260040160405180910390fd5b8315806107be5750600181015460028201546107bc9086612948565b115b156107dc5760405163162908e360e11b815260040160405180910390fd5b600085815260076020908152604080832033845282529182902082516060810184528154808252600183015493820193909352600290910154928101929092521561083a5760405163ef89654560e01b815260040160405180910390fd5b61087d3383600001548787878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061160592505050565b61089a57604051635d2f8a0560e01b815260040160405180910390fd5b848260020160008282546108ae9190612948565b9091555050604080516060808201835287825260006020808401828152428587018181528d85526007845287852033808752908552948890209651875591516001870155905160029095019490945584518b8152908101919091529283018890528201527fc69c7dfb3e15d339bfed989be99d97589fc7bb295b3ab2db82829106001b9e2d9060800160405180910390a1505050505050565b60008181526007602090815260408083206001600160a01b0386168452825280832081516060810183528154808252600183015494820185905260029092015492810192909252839290036109a257600092508291506109b2565b6109ac818561165f565b90935091505b509250929050565b60006109c5826117cf565b90506109fb6001600160a01b037f0000000000000000000000007be5dd337cc6ce3e474f64e2a92a5664452908641633836113ff565b505050565b610a0861195e565b60026003556000610a1984336119b0565b9050610a26838284611a6b565b505060016003555050565b6060818067ffffffffffffffff811115610a4d57610a4d61295b565b604051908082528060200260200182016040528015610a76578160200160208202803683370190505b50915060005b81811015610c1a57600060076000878785818110610a9c57610a9c612971565b6020908102929092013583525081810192909252604090810160009081206001600160a01b038b16825283528190208151606081018352815480825260018301549482018590526002909201549281019290925290925003610b1e576000848381518110610b0c57610b0c612971565b60200260200101818152505050610c08565b600060086000888886818110610b3657610b36612971565b602090810292909201358352508181019290925260409081016000908120825161012081018452815481526001820154948101949094526002810154928401929092526003820154606084015260048201546080840152600582015460a084015260069091015461ffff80821660c08501526201000082041660e0840152640100000000900460ff161515610100830152909150610bd48383611bf2565b9050826020015181610be69190612987565b868581518110610bf857610bf8612971565b6020026020010181815250505050505b80610c128161299a565b915050610a7c565b50509392505050565b610c2b6113ac565b600180546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a99101610697565b610c8d61195e565b60026003556000610c9e83336119b0565b9050610cab338284611a6b565b5050600160035550565b610cbd61195e565b60026003556000610cce84336119b0565b9050610a2633828585611c55565b610ce46113ac565b6000805b82811015610e1d57600060086000868685818110610d0857610d08612971565b90506020020135815260200190815260200160002090508060060160049054906101000a900460ff1615610d4f576040516336b5f2f760e11b815260040160405180910390fd5b80600401544211610d735760405163d0404f8560e01b815260040160405180910390fd5b600081600201548260010154610d899190612987565b9050610d958185612948565b60068301805464ff00000000191664010000000017905593507fadb56f2e8c8dd63466fb638690ea115eeb4f568e6e732d67200d1646b15ece75868685818110610de157610de1612971565b9050602002013582604051610e00929190918252602082015260400190565b60405180910390a150508080610e159061299a565b915050610ce8565b5080600003610e3f5760405163162908e360e11b815260040160405180910390fd5b600054610e79906001600160a01b037f0000000000000000000000007be5dd337cc6ce3e474f64e2a92a56644529086481169116836113ff565b50505050565b6000818152600760209081526040808320338452909152902080541580610eaa575060018101548154145b15610ec85760405163162908e360e11b815260040160405180910390fd5b600080610efe8360405180606001604052908160008201548152602001600182015481526020016002820154815250508561165f565b84546001860155600680549294509092508291600090610f1f908490612948565b909155505060408051858152336020820152908101839052606081018290527f1c84cc0f96161bdafea718a9094dd21c21d1fb2f9ca2ebb9bd4e39918efbaace9060800160405180910390a1610f9f6001600160a01b037f0000000000000000000000007be5dd337cc6ce3e474f64e2a92a5664452908641633846113ff565b5050505050565b6000546001600160a01b0316331480610fc957506002546001600160a01b031633145b6110095760405162461bcd60e51b815260206004820152601160248201527027b7363c9030b236b4b71037b9103232bb60791b60448201526064016105e4565b8262093a8081108061101e5750630784ce0081115b1561103c576040516337bf561360e11b815260040160405180910390fd5b858511158061104b5750428511155b15611069576040516337bf561360e11b815260040160405180910390fd5b861580611085575061271061107e83856129b3565b61ffff1610155b156110a35760405163162908e360e11b815260040160405180910390fd5b60006110da6001600160a01b037f0000000000000000000000007be5dd337cc6ce3e474f64e2a92a5664452908641633308b611d37565b90508781146110fb576040516276f4ff60e41b815260040160405180910390fd5b600060046000815461110c9061299a565b91905081905590506040518061012001604052808b81526020018a8152602001600081526020018981526020018881526020018781526020018661ffff1681526020018561ffff1681526020016000151581525060086000838152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c08201518160060160006101000a81548161ffff021916908361ffff16021790555060e08201518160060160026101000a81548161ffff021916908361ffff1602179055506101008201518160060160046101000a81548160ff0219169083151502179055509050507f9a5ab6171e45c59f905bba9a5e5d913c4457dfb38e5b695f717aa33b6b6c1362818b8b8b8b8b8b8b60405161128e989796959493929190978852602088019690965260408701949094526060860192909252608085015260a084015261ffff90811660c08401521660e08201526101000190565b60405180910390a150505050505050505050565b6112aa61195e565b600260035560006112bb85336119b0565b90506112c984828585611c55565b50506001600355505050565b6000805b82811015611320576113028484838181106112f6576112f6612971565b905060200201356117cf565b61130c9083612948565b9150806113188161299a565b9150506112d9565b50610e796001600160a01b037f0000000000000000000000007be5dd337cc6ce3e474f64e2a92a5664452908641633836113ff565b600084815260086020908152604080832054815185840281810185019093528581526113a2938a938992918991899182919085019084908082843760009201919091525061160592505050565b9695505050505050565b6000546001600160a01b031633146113fd5760405162461bcd60e51b815260206004820152601460248201527331b0b63632b91036bab9ba1031329030b236b4b760611b60448201526064016105e4565b565b600081156115fe576040516370a0823160e01b81526001600160a01b03848116600483015260009182918716906370a0823190602401602060405180830381865afa158015611452573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147691906129ce565b604080516001600160a01b038881166024830152604480830189905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151929350908816916114d091906129e7565b6000604051808303816000865af19150503d806000811461150d576040519150601f19603f3d011682016040523d82523d6000602084013e611512565b606091505b5050809250508161154a5760405162461bcd60e51b81526020600482015260026024820152612a2360f11b60448201526064016105e4565b6040516370a0823160e01b81526001600160a01b038681166004830152600091908816906370a0823190602401602060405180830381865afa158015611594573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b891906129ce565b90508181116115ee5760405162461bcd60e51b81526020600482015260026024820152612a2360f11b60448201526064016105e4565b6115f88282612987565b93505050505b9392505050565b6040516bffffffffffffffffffffffff19606086901b166020820152603481018390526000908190605401604051602081830303815290604052805190602001209050611653838683611f46565b9150505b949350505050565b6000818152600860209081526040808320815161012081018352815481526001820154938101939093526002810154918301919091526003810154606083015260048101546080830152600581015460a08301526006015461ffff80821660c08401526201000082041660e0830152640100000000900460ff1615156101008201528190816116ee8683611bf2565b90508560200151816117009190612987565b935060008260a0015187604001516117189190612948565b905060008360c0015161ffff168460a001518560e0015161ffff16428561173f9190612987565b6117499190612a16565b6117539190612a2d565b61175d9190612948565b905060008389600001516117719190612987565b90506127106117808383612a16565b61178a9190612a2d565b95508086106117ac5760405163458eae5b60e01b815260040160405180910390fd5b6117b68682612987565b6117c09088612948565b965050505050505b9250929050565b60008181526007602090815260408083203384529091528120805415806117fa575060018101548154145b156118185760405163162908e360e11b815260040160405180910390fd5b6000838152600860209081526040808320815161012081018352815481526001808301548286015260028084015483860152600384015460608085019190915260048501546080850152600585015460a085015260069094015461ffff80821660c08601526201000082041660e0850152640100000000900460ff16151561010084015290870154845193840185528754845294830185905286015492820192909252909291906118c99084611bf2565b6118d39190612987565b9050806000036118f65760405163162908e360e11b815260040160405180910390fd5b8083600101600082825461190a9190612948565b909155505060408051868152336020820152908101829052600060608201527f1c84cc0f96161bdafea718a9094dd21c21d1fb2f9ca2ebb9bd4e39918efbaace9060800160405180910390a1949350505050565b6002600354036113fd5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016105e4565b60008281526007602090815260408083206001600160a01b038516845290915281206001810154815483916119e491612987565b825490915015806119f3575080155b15611a115760405163162908e360e11b815260040160405180910390fd5b81546001830155604080518681526001600160a01b03861660208201529081018290527f0235b6790a877095b8878d0a0e0af7c5442875c0ac9f901c07584ff6f71d9d6d9060600160405180910390a19150505b92915050565b60405163cbf9fe5f60e01b81526001600160a01b0384811660048301526000917f0000000000000000000000001c59529ba394427d9a18a3ef6b8ca38906b8e2db9091169063cbf9fe5f906024016040805180830381865afa158015611ad5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af99190612a4f565b915050611b0581611f5c565b6000611b118484611fa3565b9050611b676001600160a01b037f000000000000000000000000fdb2c36b73e18871d9208cc508c911a1bffcfb8e167f0000000000000000000000001c59529ba394427d9a18a3ef6b8ca38906b8e2db83612168565b5060405163743241bb60e11b81526001600160a01b038681166004830152602482018390527f0000000000000000000000001c59529ba394427d9a18a3ef6b8ca38906b8e2db169063e8648376906044015b600060405180830381600087803b158015611bd357600080fd5b505af1158015611be7573d6000803e3d6000fd5b505050505050505050565b6000808260a001518460400151611c099190612948565b905080421115611c1c5750508151611a65565b60a083015184516040860151611c329042612987565b611c3c9190612a16565b611c469190612a2d565b915050611a65565b5092915050565b62093a80611c638183612a2d565b611c6d9190612a16565b9050611c7881611f5c565b6000611c848484611fa3565b9050611cda6001600160a01b037f000000000000000000000000fdb2c36b73e18871d9208cc508c911a1bffcfb8e167f0000000000000000000000001c59529ba394427d9a18a3ef6b8ca38906b8e2db83612168565b50604051633e173b2960e01b81526001600160a01b03868116600483015260248201839052604482018490527f0000000000000000000000001c59529ba394427d9a18a3ef6b8ca38906b8e2db1690633e173b2990606401611bb9565b60008115611657576040516370a0823160e01b81526001600160a01b03848116600483015260009182918816906370a0823190602401602060405180830381865afa158015611d8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dae91906129ce565b604080516001600160a01b0389811660248301528881166044830152606480830189905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b179052915192935090891691611e1091906129e7565b6000604051808303816000865af19150503d8060008114611e4d576040519150601f19603f3d011682016040523d82523d6000602084013e611e52565b606091505b50508092505081611e8b5760405162461bcd60e51b81526020600482015260036024820152622a232360e91b60448201526064016105e4565b6040516370a0823160e01b81526001600160a01b038681166004830152600091908916906370a0823190602401602060405180830381865afa158015611ed5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef991906129ce565b9050818111611f305760405162461bcd60e51b81526020600482015260036024820152622a232360e91b60448201526064016105e4565b611f3a8282612987565b98975050505050505050565b600082611f538584612400565b14949350505050565b600554611f699042612948565b811080611f825750611f7f630784ce0042612948565b81115b15611fa0576040516337bf561360e11b815260040160405180910390fd5b50565b6000806000611ff27f0000000000000000000000007be5dd337cc6ce3e474f64e2a92a5664452908647f000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e583161244d565b90925090506000826120048388612a16565b61200e9190612a2d565b9050848111156120335760405162d3c55f60e61b8152600481018290526024016105e4565b6120886001600160a01b037f000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e583116337f000000000000000000000000fdb2c36b73e18871d9208cc508c911a1bffcfb8e84611d37565b506120dd6001600160a01b037f0000000000000000000000007be5dd337cc6ce3e474f64e2a92a566445290864167f000000000000000000000000fdb2c36b73e18871d9208cc508c911a1bffcfb8e886113ff565b506040516335313c2160e11b81523060048201527f000000000000000000000000fdb2c36b73e18871d9208cc508c911a1bffcfb8e6001600160a01b031690636a627842906024016020604051808303816000875af1158015612144573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a291906129ce565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091829186169063dd62ed3e90604401602060405180830381865afa1580156121b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121dd91906129ce565b156122b657604080516001600160a01b038681166024830152600060448084019190915283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b17905291519187169161223c91906129e7565b6000604051808303816000865af19150503d8060008114612279576040519150601f19603f3d011682016040523d82523d6000602084013e61227e565b606091505b505080915050806122b65760405162461bcd60e51b815260206004820152600260248201526120a360f11b60448201526064016105e4565b604080516001600160a01b038681166024830152604480830187905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b17905291519187169161230d91906129e7565b6000604051808303816000865af19150503d806000811461234a576040519150601f19603f3d011682016040523d82523d6000602084013e61234f565b606091505b505080915050806123875760405162461bcd60e51b815260206004820152600260248201526120a360f11b60448201526064016105e4565b604051636eb1769f60e11b81523060048201526001600160a01b03858116602483015286169063dd62ed3e90604401602060405180830381865afa1580156123d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123f791906129ce565b95945050505050565b600081815b8451811015612445576124318286838151811061242457612424612971565b6020026020010151612545565b91508061243d8161299a565b915050612405565b509392505050565b6000806000807f000000000000000000000000fdb2c36b73e18871d9208cc508c911a1bffcfb8e6001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156124b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124d59190612a8a565b506001600160701b031691506001600160701b031691506000856001600160a01b0316876001600160a01b03161061250e578587612511565b86865b509050806001600160a01b0316876001600160a01b031614612534578183612537565b82825b909890975095505050505050565b60008183106125615760008281526020849052604090206115fe565b5060009182526020526040902090565b60006020828403121561258357600080fd5b5035919050565b60008083601f84011261259c57600080fd5b50813567ffffffffffffffff8111156125b457600080fd5b6020830191508360208260051b85010111156117c857600080fd5b600080600080606085870312156125e557600080fd5b8435935060208501359250604085013567ffffffffffffffff81111561260a57600080fd5b6126168782880161258a565b95989497509550505050565b6001600160a01b0381168114611fa057600080fd5b6000806040838503121561264a57600080fd5b823561265581612622565b946020939093013593505050565b60008060006060848603121561267857600080fd5b83359250602084013561268a81612622565b929592945050506040919091013590565b6000806000604084860312156126b057600080fd5b83356126bb81612622565b9250602084013567ffffffffffffffff8111156126d757600080fd5b6126e38682870161258a565b9497909650939450505050565b6020808252825182820181905260009190848201906040850190845b818110156127285783518352928401929184019160010161270c565b50909695505050505050565b60006020828403121561274657600080fd5b81356115fe81612622565b6000806040838503121561276457600080fd5b50508035926020909101359150565b60008060006060848603121561278857600080fd5b505081359360208301359350604090920135919050565b600080602083850312156127b257600080fd5b823567ffffffffffffffff8111156127c957600080fd5b6127d58582860161258a565b90969095509350505050565b803561ffff811681146127f357600080fd5b919050565b600080600080600080600060e0888a03121561281357600080fd5b873596506020880135955060408801359450606088013593506080880135925061283f60a089016127e1565b915061284d60c089016127e1565b905092959891949750929550565b6000806000806080858703121561287157600080fd5b84359350602085013561288381612622565b93969395505050506040820135916060013590565b6000806000806000608086880312156128b057600080fd5b85356128bb81612622565b94506020860135935060408601359250606086013567ffffffffffffffff8111156128e557600080fd5b6128f18882890161258a565b969995985093965092949392505050565b6000806040838503121561291557600080fd5b82359150602083013561292781612622565b809150509250929050565b634e487b7160e01b600052601160045260246000fd5b80820180821115611a6557611a65612932565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b81810381811115611a6557611a65612932565b6000600182016129ac576129ac612932565b5060010190565b61ffff818116838216019080821115611c4e57611c4e612932565b6000602082840312156129e057600080fd5b5051919050565b6000825160005b81811015612a0857602081860181015185830152016129ee565b506000920191825250919050565b8082028115828204841417611a6557611a65612932565b600082612a4a57634e487b7160e01b600052601260045260246000fd5b500490565b60008060408385031215612a6257600080fd5b505080516020909101519092909150565b80516001600160701b03811681146127f357600080fd5b600080600060608486031215612a9f57600080fd5b612aa884612a73565b9250612ab660208501612a73565b9150604084015163ffffffff81168114612acf57600080fd5b80915050925092509256fea2646970667358221220e8750343cb1fe1e65198b0a3e5bac082b2a8897d600a33e5ce0f7e8108ab210364736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000007be5dd337cc6ce3e474f64e2a92a566445290864000000000000000000000000fdb2c36b73e18871d9208cc508c911a1bffcfb8e000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e58310000000000000000000000001c59529ba394427d9a18a3ef6b8ca38906b8e2db000000000000000000000000000000000000000000000000000000000024ea00
-----Decoded View---------------
Arg [0] : _oleToken (address): 0x7Be5Dd337CC6cE3e474F64E2A92A566445290864
Arg [1] : _pair (address): 0xFdB2C36b73e18871D9208cc508c911A1bFFCFB8e
Arg [2] : _token1 (address): 0xaf88d065e77c8cC2239327C5EDb3A432268e5831
Arg [3] : _xole (address): 0x1c59529ba394427D9a18A3eF6B8CA38906b8E2dB
Arg [4] : _minXOLELockDuration (uint256): 2419200
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000007be5dd337cc6ce3e474f64e2a92a566445290864
Arg [1] : 000000000000000000000000fdb2c36b73e18871d9208cc508c911a1bffcfb8e
Arg [2] : 000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e5831
Arg [3] : 0000000000000000000000001c59529ba394427d9a18a3ef6b8ca38906b8e2db
Arg [4] : 000000000000000000000000000000000000000000000000000000000024ea00
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$386.35
Net Worth in ETH
0.163813
Token Allocations
OLE
100.00%
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ARB | 100.00% | $0.00157 | 246,004.2669 | $386.35 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.