Source Code
Overview
GLMR Balance
GLMR Value
$0.00| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784697 | 42 days ago | 0 GLMR | ||||
| 13784691 | 42 days ago | 0 GLMR | ||||
| 13784691 | 42 days ago | 0 GLMR |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
StableSwapStorage
Compiler Version
v0.8.4+commit.c7e474f2
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.4;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./LPToken.sol";
/**
* StableSwap main algorithm
*/
library StableSwapStorage {
using SafeERC20 for IERC20;
event AddLiquidity(
address indexed provider,
uint256[] token_amounts,
uint256[] fees,
uint256 invariant,
uint256 token_supply
);
event TokenExchange(
address indexed buyer,
uint256 sold_id,
uint256 tokens_sold,
uint256 bought_id,
uint256 tokens_bought
);
event RemoveLiquidity(address indexed provider, uint256[] token_amounts, uint256[] fees, uint256 token_supply);
event RemoveLiquidityOne(address indexed provider, uint256 index, uint256 token_amount, uint256 coin_amount);
event RemoveLiquidityImbalance(
address indexed provider,
uint256[] token_amounts,
uint256[] fees,
uint256 invariant,
uint256 token_supply
);
uint256 public constant FEE_DENOMINATOR = 1e10;
// uint256 public constant PRECISION = 1e18;
/// @dev protect from division loss when run approximation loop. We cannot divide at the end because of overflow,
/// so we add some (small) PRECISION when divide in each iteration
uint256 public constant A_PRECISION = 100;
/// @dev max iteration of converge calccuate
uint256 internal constant MAX_ITERATION = 256;
uint256 public constant POOL_TOKEN_COMMON_DECIMALS = 18;
struct SwapStorage {
IERC20[] pooledTokens;
LPToken lpToken;
/// @dev token i multiplier to reach POOL_TOKEN_COMMON_DECIMALS
uint256[] tokenMultipliers;
/// @dev effective balance which might different from token balance of the contract 'cause it hold admin fee as well
uint256[] balances;
/// @dev swap fee ratio. Charge on any action which move balance state far from the ideal state
uint256 fee;
/// @dev admin fee in ratio of swap fee.
uint256 adminFee;
/// @dev observation of A, multiplied with A_PRECISION
uint256 initialA;
uint256 futureA;
uint256 initialATime;
uint256 futureATime;
}
/**
* @notice Deposit coins into the pool
* @param amounts List of amounts of coins to deposit
* @param minMintAmount Minimum amount of LP tokens to mint from the deposit
* @return mintAmount Amount of LP tokens received by depositing
*/
function addLiquidity(
SwapStorage storage self,
uint256[] memory amounts,
uint256 minMintAmount
) external returns (uint256 mintAmount) {
uint256 nCoins = self.pooledTokens.length;
require(amounts.length == nCoins, "invalidAmountsLength");
uint256[] memory fees = new uint256[](nCoins);
uint256 _fee = _feePerToken(self);
uint256 tokenSupply = self.lpToken.totalSupply();
uint256 amp = _getAPrecise(self);
uint256 D0 = 0;
if (tokenSupply > 0) {
D0 = _getD(_xp(self.balances, self.tokenMultipliers), amp);
}
uint256[] memory newBalances = self.balances;
for (uint256 i = 0; i < nCoins; i++) {
if (tokenSupply == 0) {
require(amounts[i] > 0, "initialDepositRequireAllTokens");
}
// get real transfer in amount
newBalances[i] += _doTransferIn(self.pooledTokens[i], amounts[i]);
}
uint256 D1 = _getD(_xp(newBalances, self.tokenMultipliers), amp);
assert(D1 > D0); // double check
if (tokenSupply == 0) {
self.balances = newBalances;
mintAmount = D1;
} else {
uint256 diff = 0;
for (uint256 i = 0; i < nCoins; i++) {
diff = _distance((D1 * self.balances[i]) / D0, newBalances[i]);
fees[i] = (_fee * diff) / FEE_DENOMINATOR;
self.balances[i] = newBalances[i] - ((fees[i] * self.adminFee) / FEE_DENOMINATOR);
newBalances[i] -= fees[i];
}
D1 = _getD(_xp(newBalances, self.tokenMultipliers), amp);
mintAmount = (tokenSupply * (D1 - D0)) / D0;
}
require(mintAmount >= minMintAmount, "> slippage");
self.lpToken.mint(msg.sender, mintAmount);
emit AddLiquidity(msg.sender, amounts, fees, D1, mintAmount);
}
function swap(
SwapStorage storage self,
uint256 i,
uint256 j,
uint256 inAmount,
uint256 minOutAmount
) external returns (uint256) {
IERC20 inCoin = self.pooledTokens[i];
uint256[] memory normalizedBalances = _xp(self);
inAmount = _doTransferIn(inCoin, inAmount);
uint256 x = normalizedBalances[i] + (inAmount * self.tokenMultipliers[i]);
uint256 y = _getY(self, i, j, x, normalizedBalances);
uint256 dy = normalizedBalances[j] - y - 1; // iliminate rouding errors
uint256 dy_fee = (dy * self.fee) / FEE_DENOMINATOR;
dy = (dy - dy_fee) / self.tokenMultipliers[j]; // denormalize
require(dy >= minOutAmount, "> slippage");
uint256 _adminFee = (dy_fee * self.adminFee) / FEE_DENOMINATOR / self.tokenMultipliers[j];
// update balances
self.balances[i] += inAmount;
self.balances[j] -= dy + _adminFee;
self.pooledTokens[j].safeTransfer(msg.sender, dy);
emit TokenExchange(msg.sender, i, inAmount, j, dy);
return dy;
}
function removeLiquidity(
SwapStorage storage self,
uint256 lpAmount,
uint256[] memory minAmounts
) external returns (uint256[] memory amounts) {
uint256 totalSupply = self.lpToken.totalSupply();
require(lpAmount <= totalSupply);
uint256 nCoins = self.pooledTokens.length;
uint256[] memory fees = new uint256[](nCoins);
amounts = _calculateRemoveLiquidity(self, lpAmount);
for (uint256 i = 0; i < amounts.length; i++) {
require(amounts[i] >= minAmounts[i], "> slippage");
self.balances[i] = self.balances[i] - amounts[i];
self.pooledTokens[i].safeTransfer(msg.sender, amounts[i]);
}
self.lpToken.burnFrom(msg.sender, lpAmount);
emit RemoveLiquidity(msg.sender, amounts, fees, totalSupply - lpAmount);
}
function removeLiquidityOneToken(
SwapStorage storage self,
uint256 lpAmount,
uint256 index,
uint256 minAmount
) external returns (uint256) {
uint256 totalSupply = self.lpToken.totalSupply();
require(totalSupply > 0, "totalSupply = 0");
uint256 numTokens = self.pooledTokens.length;
require(lpAmount <= self.lpToken.balanceOf(msg.sender), "> balance");
require(lpAmount <= totalSupply, "> totalSupply");
require(index < numTokens, "tokenNotFound");
uint256 dyFee;
uint256 dy;
(dy, dyFee) = _calculateRemoveLiquidityOneToken(self, lpAmount, index);
require(dy >= minAmount, "> slippage");
self.balances[index] -= (dy + (dyFee * self.adminFee) / FEE_DENOMINATOR);
self.lpToken.burnFrom(msg.sender, lpAmount);
self.pooledTokens[index].safeTransfer(msg.sender, dy);
emit RemoveLiquidityOne(msg.sender, index, lpAmount, dy);
return dy;
}
function removeLiquidityImbalance(
SwapStorage storage self,
uint256[] memory amounts,
uint256 maxBurnAmount
) external returns (uint256 burnAmount) {
uint256 nCoins = self.pooledTokens.length;
require(amounts.length == nCoins, "invalidAmountsLength");
uint256 totalSupply = self.lpToken.totalSupply();
require(totalSupply != 0, "totalSupply = 0");
uint256 _fee = _feePerToken(self);
uint256 amp = _getAPrecise(self);
uint256[] memory newBalances = self.balances;
uint256 D0 = _getD(_xp(self), amp);
for (uint256 i = 0; i < nCoins; i++) {
newBalances[i] -= amounts[i];
}
uint256 D1 = _getD(_xp(newBalances, self.tokenMultipliers), amp);
uint256[] memory fees = new uint256[](nCoins);
for (uint256 i = 0; i < nCoins; i++) {
uint256 idealBalance = (D1 * self.balances[i]) / D0;
uint256 diff = _distance(newBalances[i], idealBalance);
fees[i] = (_fee * diff) / FEE_DENOMINATOR;
self.balances[i] = newBalances[i] - ((fees[i] * self.adminFee) / FEE_DENOMINATOR);
newBalances[i] -= fees[i];
}
// recalculate invariant with fee charged balances
D1 = _getD(_xp(newBalances, self.tokenMultipliers), amp);
burnAmount = ((D0 - D1) * totalSupply) / D0;
assert(burnAmount > 0);
require(burnAmount <= maxBurnAmount, "> slippage");
self.lpToken.burnFrom(msg.sender, burnAmount);
for (uint256 i = 0; i < nCoins; i++) {
if (amounts[i] != 0) {
self.pooledTokens[i].safeTransfer(msg.sender, amounts[i]);
}
}
emit RemoveLiquidityImbalance(msg.sender, amounts, fees, D1, totalSupply - burnAmount);
}
/// VIEW FUNCTIONS
function getAPrecise(SwapStorage storage self) external view returns (uint256) {
return _getAPrecise(self);
}
/**
* Returns portfolio virtual price (for calculating profit)
* scaled up by 1e18
*/
function getVirtualPrice(SwapStorage storage self) external view returns (uint256) {
uint256 D = _getD(_xp(self), _getAPrecise(self));
uint256 tokenSupply = self.lpToken.totalSupply();
return (D * 10**POOL_TOKEN_COMMON_DECIMALS) / tokenSupply;
}
function getAdminBalance(SwapStorage storage self, uint256 index) external view returns (uint256) {
require(index < self.pooledTokens.length, "indexOutOfRange");
return self.pooledTokens[index].balanceOf(address(this)) - (self.balances[index]);
}
/**
* Estimate amount of LP token minted or burned at deposit or withdrawal
* without taking fees into account
*/
function calculateTokenAmount(
SwapStorage storage self,
uint256[] memory amounts,
bool deposit
) external view returns (uint256) {
uint256 nCoins = self.pooledTokens.length;
require(amounts.length == nCoins, "invalidAmountsLength");
uint256 amp = _getAPrecise(self);
uint256 D0 = _getD(_xp(self), amp);
uint256[] memory newBalances = self.balances;
for (uint256 i = 0; i < nCoins; i++) {
if (deposit) {
newBalances[i] += amounts[i];
} else {
newBalances[i] -= amounts[i];
}
}
uint256 D1 = _getD(_xp(newBalances, self.tokenMultipliers), amp);
uint256 totalSupply = self.lpToken.totalSupply();
if (totalSupply == 0) {
return D1; // first depositor take it all
}
uint256 diff = deposit ? D1 - D0 : D0 - D1;
return (diff * self.lpToken.totalSupply()) / D0;
}
function getA(SwapStorage storage self) external view returns (uint256) {
return _getAPrecise(self) / A_PRECISION;
}
function calculateSwap(
SwapStorage storage self,
uint256 inIndex,
uint256 outIndex,
uint256 inAmount
) external view returns (uint256) {
uint256[] memory normalizedBalances = _xp(self);
uint256 newInBalance = normalizedBalances[inIndex] + (inAmount * self.tokenMultipliers[inIndex]);
uint256 outBalance = _getY(self, inIndex, outIndex, newInBalance, normalizedBalances);
uint256 outAmount = (normalizedBalances[outIndex] - outBalance - 1) / self.tokenMultipliers[outIndex];
uint256 _fee = (self.fee * outAmount) / FEE_DENOMINATOR;
return outAmount - _fee;
}
function calculateRemoveLiquidity(SwapStorage storage self, uint256 amount)
external
view
returns (uint256[] memory)
{
return _calculateRemoveLiquidity(self, amount);
}
function calculateRemoveLiquidityOneToken(
SwapStorage storage self,
uint256 lpAmount,
uint256 tokenIndex
) external view returns (uint256 amount) {
(amount, ) = _calculateRemoveLiquidityOneToken(self, lpAmount, tokenIndex);
}
/// INTERNAL FUNCTIONS
/**
* Ramping A up or down, return A with precision of A_PRECISION
*/
function _getAPrecise(SwapStorage storage self) internal view returns (uint256) {
if (block.timestamp >= self.futureATime) {
return self.futureA;
}
if (self.futureA > self.initialA) {
return
self.initialA +
((self.futureA - self.initialA) * (block.timestamp - self.initialATime)) /
(self.futureATime - self.initialATime);
}
return
self.initialA -
((self.initialA - self.futureA) * (block.timestamp - self.initialATime)) /
(self.futureATime - self.initialATime);
}
/**
* normalized balances of each tokens.
*/
function _xp(uint256[] memory balances, uint256[] memory rates) internal pure returns (uint256[] memory) {
for (uint256 i = 0; i < balances.length; i++) {
rates[i] = (rates[i] * balances[i]);
}
return rates;
}
function _xp(SwapStorage storage self) internal view returns (uint256[] memory) {
return _xp(self.balances, self.tokenMultipliers);
}
/**
* Calculate D for *NORMALIZED* balances of each tokens
* @param xp normalized balances of token
*/
function _getD(uint256[] memory xp, uint256 amp) internal pure returns (uint256) {
uint256 nCoins = xp.length;
uint256 sum = _sumOf(xp);
if (sum == 0) {
return 0;
}
uint256 Dprev = 0;
uint256 D = sum;
uint256 Ann = amp * nCoins;
for (uint256 i = 0; i < MAX_ITERATION; i++) {
uint256 D_P = D;
for (uint256 j = 0; j < xp.length; j++) {
D_P = (D_P * D) / (xp[j] * nCoins);
}
Dprev = D;
D =
(((Ann * sum) / A_PRECISION + D_P * nCoins) * D) /
(((Ann - A_PRECISION) * D) / A_PRECISION + (nCoins + 1) * D_P);
if (_distance(D, Dprev) <= 1) {
return D;
}
}
// Convergence should occur in 4 loops or less. If this is reached, there may be something wrong
// with the pool. If this were to occur repeatedly, LPs should withdraw via `removeLiquidity()`
// function which does not rely on D.
revert("invariantCalculationFailed");
}
/**
* calculate new balance of when swap
* Done by solving quadratic equation iteratively.
* x_1**2 + x_1 * (sum' - (A*n**n - 1) * D / (A * n**n)) = D ** (n + 1) / (n ** (2 * n) * prod' * A)
* x_1**2 + b*x_1 = c
* x_1 = (x_1**2 + c) / (2*x_1 + b)
* @param inIndex index of token to swap in
* @param outIndex index of token to swap out
* @param inBalance new balance (normalized) of input token if the swap success
* @return NORMALIZED balance of output token if the swap success
*/
function _getY(
SwapStorage storage self,
uint256 inIndex,
uint256 outIndex,
uint256 inBalance,
uint256[] memory normalizedBalances
) internal view returns (uint256) {
require(inIndex != outIndex, "sameToken");
uint256 nCoins = self.pooledTokens.length;
require(inIndex < nCoins && outIndex < nCoins, "indexOutOfRange");
uint256 amp = _getAPrecise(self);
uint256 Ann = amp * nCoins;
uint256 D = _getD(normalizedBalances, amp);
uint256 sum = 0; // sum of new balances except output token
uint256 c = D;
for (uint256 i = 0; i < nCoins; i++) {
if (i == outIndex) {
continue;
}
uint256 x = i == inIndex ? inBalance : normalizedBalances[i];
sum += x;
c = (c * D) / (x * nCoins);
}
c = (c * D * A_PRECISION) / (Ann * nCoins);
uint256 b = sum + (D * A_PRECISION) / Ann;
uint256 lastY = 0;
uint256 y = D;
for (uint256 index = 0; index < MAX_ITERATION; index++) {
lastY = y;
y = (y * y + c) / (2 * y + b - D);
if (_distance(lastY, y) <= 1) {
return y;
}
}
revert("yCalculationFailed");
}
function _calculateRemoveLiquidity(SwapStorage storage self, uint256 amount)
internal
view
returns (uint256[] memory)
{
uint256 totalSupply = self.lpToken.totalSupply();
require(amount <= totalSupply, "Cannot exceed total supply");
uint256[] memory amounts = new uint256[](self.pooledTokens.length);
for (uint256 i = 0; i < self.pooledTokens.length; i++) {
amounts[i] = (self.balances[i] * (amount)) / (totalSupply);
}
return amounts;
}
function _calculateRemoveLiquidityOneToken(
SwapStorage storage self,
uint256 tokenAmount,
uint256 index
) internal view returns (uint256 dy, uint256 fee) {
require(index < self.pooledTokens.length, "indexOutOfRange");
uint256 amp = _getAPrecise(self);
uint256[] memory xp = _xp(self);
uint256 D0 = _getD(xp, amp);
uint256 D1 = D0 - (tokenAmount * D0) / self.lpToken.totalSupply();
uint256 newY = _getYD(self, amp, index, xp, D1);
uint256[] memory reducedXP = xp;
uint256 _fee = _feePerToken(self);
for (uint256 i = 0; i < self.pooledTokens.length; i++) {
uint256 expectedDx = 0;
if (i == index) {
expectedDx = (xp[i] * D1) / D0 - newY;
} else {
expectedDx = xp[i] - (xp[i] * D1) / D0;
}
reducedXP[i] -= (_fee * expectedDx) / FEE_DENOMINATOR;
}
dy = reducedXP[index] - _getYD(self, amp, index, reducedXP, D1);
dy = (dy - 1) / self.tokenMultipliers[index];
fee = ((xp[index] - newY) / self.tokenMultipliers[index]) - dy;
}
function _feePerToken(SwapStorage storage self) internal view returns (uint256) {
uint256 nCoins = self.pooledTokens.length;
return (self.fee * nCoins) / (4 * (nCoins - 1));
}
function _getYD(
SwapStorage storage self,
uint256 A,
uint256 index,
uint256[] memory xp,
uint256 D
) internal view returns (uint256) {
uint256 nCoins = self.pooledTokens.length;
assert(index < nCoins);
uint256 Ann = A * nCoins;
uint256 c = D;
uint256 s = 0;
uint256 _x = 0;
uint256 yPrev = 0;
for (uint256 i = 0; i < nCoins; i++) {
if (i == index) {
continue;
}
_x = xp[i];
s += _x;
c = (c * D) / (_x * nCoins);
}
c = (c * D * A_PRECISION) / (Ann * nCoins);
uint256 b = s + (D * A_PRECISION) / Ann;
uint256 y = D;
for (uint256 i = 0; i < MAX_ITERATION; i++) {
yPrev = y;
y = (y * y + c) / (2 * y + b - D);
if (_distance(yPrev, y) <= 1) {
return y;
}
}
revert("invariantCalculationFailed");
}
function _doTransferIn(IERC20 token, uint256 amount) internal returns (uint256) {
uint256 priorBalance = token.balanceOf(address(this));
token.safeTransferFrom(msg.sender, address(this), amount);
return token.balanceOf(address(this)) - priorBalance;
}
function _sumOf(uint256[] memory x) internal pure returns (uint256 sum) {
sum = 0;
for (uint256 i = 0; i < x.length; i++) {
sum += x[i];
}
}
function _distance(uint256 x, uint256 y) internal pure returns (uint256) {
return x > y ? x - y : y - x;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_setOwner(_msgSender());
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_setOwner(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_setOwner(newOwner);
}
function _setOwner(address newOwner) private {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* The default value of {decimals} is 18. To select a different value for
* {decimals} you should overload it.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the value {ERC20} uses, unless this function is
* overridden;
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `recipient` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* Requirements:
*
* - `sender` and `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
* - the caller must have allowance for ``sender``'s tokens of at least
* `amount`.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
uint256 currentAllowance = _allowances[sender][_msgSender()];
require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
unchecked {
_approve(sender, _msgSender(), currentAllowance - amount);
}
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
uint256 currentAllowance = _allowances[_msgSender()][spender];
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(_msgSender(), spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `amount` of tokens from `sender` to `recipient`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `sender` cannot be the zero address.
* - `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
*/
function _transfer(
address sender,
address recipient,
uint256 amount
) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[sender] = senderBalance - amount;
}
_balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
_afterTokenTransfer(sender, recipient, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
}
_totalSupply -= amount;
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @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 `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, 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 `sender` to `recipient` 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 sender,
address recipient,
uint256 amount
) external returns (bool);
/**
* @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);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../ERC20.sol";
import "../../../utils/Context.sol";
/**
* @dev Extension of {ERC20} that allows token holders to destroy both their own
* tokens and those that they have an allowance for, in a way that can be
* recognized off-chain (via event analysis).
*/
abstract contract ERC20Burnable is Context, ERC20 {
/**
* @dev Destroys `amount` tokens from the caller.
*
* See {ERC20-_burn}.
*/
function burn(uint256 amount) public virtual {
_burn(_msgSender(), amount);
}
/**
* @dev Destroys `amount` tokens from `account`, deducting from the caller's
* allowance.
*
* See {ERC20-_burn} and {ERC20-allowance}.
*
* Requirements:
*
* - the caller must have allowance for ``accounts``'s tokens of at least
* `amount`.
*/
function burnFrom(address account, uint256 amount) public virtual {
uint256 currentAllowance = allowance(account, _msgSender());
require(currentAllowance >= amount, "ERC20: burn amount exceeds allowance");
unchecked {
_approve(account, _msgSender(), currentAllowance - amount);
}
_burn(account, amount);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
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");
(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");
(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");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal 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
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @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 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 Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.4;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IStableSwap {
/// EVENTS
event AddLiquidity(
address indexed provider,
uint256[] tokenAmounts,
uint256[] fees,
uint256 invariant,
uint256 tokenSupply
);
event TokenExchange(
address indexed buyer,
uint256 soldId,
uint256 tokensSold,
uint256 boughtId,
uint256 tokensBought
);
event RemoveLiquidity(address indexed provider, uint256[] tokenAmounts, uint256[] fees, uint256 tokenSupply);
event RemoveLiquidityOne(address indexed provider, uint256 tokenIndex, uint256 tokenAmount, uint256 coinAmount);
event RemoveLiquidityImbalance(
address indexed provider,
uint256[] tokenAmounts,
uint256[] fees,
uint256 invariant,
uint256 tokenSupply
);
event RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime);
event StopRampA(uint256 A, uint256 timestamp);
event NewFee(uint256 fee, uint256 adminFee);
event CollectProtocolFee(address token, uint256 amount);
event FeeControllerChanged(address newController);
event FeeDistributorChanged(address newController);
// pool data view functions
function getLpToken() external view returns (IERC20 lpToken);
function getA() external view returns (uint256);
function getAPrecise() external view returns (uint256);
function getToken(uint8 index) external view returns (IERC20);
function getTokens() external view returns (IERC20[] memory);
function getTokenIndex(address tokenAddress) external view returns (uint8);
function getTokenBalance(uint8 index) external view returns (uint256);
function getTokenBalances() external view returns (uint256[] memory);
function getNumberOfTokens() external view returns (uint256);
function getVirtualPrice() external view returns (uint256);
function calculateTokenAmount(uint256[] calldata amounts, bool deposit) external view returns (uint256);
function calculateSwap(
uint8 tokenIndexFrom,
uint8 tokenIndexTo,
uint256 dx
) external view returns (uint256);
function calculateRemoveLiquidity(uint256 amount) external view returns (uint256[] memory);
function calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex)
external
view
returns (uint256 availableTokenAmount);
function getAdminBalances() external view returns (uint256[] memory adminBalances);
function getAdminBalance(uint8 index) external view returns (uint256);
// state modifying functions
function swap(
uint8 tokenIndexFrom,
uint8 tokenIndexTo,
uint256 dx,
uint256 minDy,
uint256 deadline
) external returns (uint256);
function addLiquidity(
uint256[] calldata amounts,
uint256 minToMint,
uint256 deadline
) external returns (uint256);
function removeLiquidity(
uint256 amount,
uint256[] calldata minAmounts,
uint256 deadline
) external returns (uint256[] memory);
function removeLiquidityOneToken(
uint256 tokenAmount,
uint8 tokenIndex,
uint256 minAmount,
uint256 deadline
) external returns (uint256);
function removeLiquidityImbalance(
uint256[] calldata amounts,
uint256 maxBurnAmount,
uint256 deadline
) external returns (uint256);
function withdrawAdminFee() external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "../interfaces/IStableSwap.sol";
contract LPToken is Ownable, ERC20Burnable {
IStableSwap public swap;
constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) {
swap = IStableSwap(msg.sender);
}
function mint(address _to, uint256 _amount) external onlyOwner {
require(_amount > 0, "zeroMintAmount");
_mint(_to, _amount);
}
}{
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [],
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"token_amounts","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"fees","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"invariant","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"token_supply","type":"uint256"}],"name":"AddLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"token_amounts","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"fees","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"token_supply","type":"uint256"}],"name":"RemoveLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"token_amounts","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"fees","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"invariant","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"token_supply","type":"uint256"}],"name":"RemoveLiquidityImbalance","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"token_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"coin_amount","type":"uint256"}],"name":"RemoveLiquidityOne","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"sold_id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokens_sold","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bought_id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokens_bought","type":"uint256"}],"name":"TokenExchange","type":"event"},{"inputs":[],"name":"A_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEE_DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POOL_TOKEN_COMMON_DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
6138ee61003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361061010a5760003560e01c8063b9510fc8116100a1578063d73792a911610070578063d73792a914610231578063e42f75fa1461023d578063ec623a1e1461025d578063f94eed871461027057600080fd5b8063b9510fc8146101e1578063c20aace8146101f4578063d011f918146101fc578063d0b1a0051461020457600080fd5b80634ddd2918116100dd5780634ddd29181461017b578063576b97351461018e5780637461cf1b146101ae5780638ce65d8e146101c157600080fd5b80630a1368cd1461010f57806337ac5bea146101355780633a8d10bd1461014857806345b69ab714610168575b600080fd5b61012261011d366004613407565b610283565b6040519081526020015b60405180910390f35b610122610143366004613348565b610397565b81801561015457600080fd5b506101226101633660046134d2565b61046b565b610122610176366004613360565b610798565b610122610189366004613476565b610af7565b81801561019a57600080fd5b506101226101a93660046133b9565b610b0d565b6101226101bc366004613348565b6111b8565b8180156101cd57600080fd5b506101226101dc3660046134a1565b6111c3565b6101226101ef366004613348565b611545565b610122601281565b610122606481565b81801561021057600080fd5b5061022461021f366004613428565b61155c565b60405161012c919061357a565b6101226402540be40081565b81801561024957600080fd5b506101226102583660046133b9565b61187f565b61012261026b3660046134a1565b611fbf565b61022461027e366004613407565b612104565b815460009082106102af5760405162461bcd60e51b81526004016102a690613660565b60405180910390fd5b8260030182815481106102d257634e487b7160e01b600052603260045260246000fd5b906000526020600020015483600001838154811061030057634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561034c57600080fd5b505afa158015610360573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610384919061350c565b61038e919061381d565b90505b92915050565b6000806103b46103a684612110565b6103af856121be565b612297565b905060008360010160009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561040857600080fd5b505afa15801561041c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610440919061350c565b90508061044f6012600a613756565b61045990846137fe565b61046391906136f3565b949350505050565b60008086600001868154811061049157634e487b7160e01b600052603260045260246000fd5b60009182526020822001546001600160a01b031691506104b088612110565b90506104bc8286612441565b945060008860020188815481106104e357634e487b7160e01b600052603260045260246000fd5b9060005260206000200154866104f991906137fe565b82898151811061051957634e487b7160e01b600052603260045260246000fd5b602002602001015161052b91906136db565b9050600061053c8a8a8a8587612557565b90506000600182858b8151811061056357634e487b7160e01b600052603260045260246000fd5b6020026020010151610575919061381d565b61057f919061381d565b905060006402540be4008c600401548361059991906137fe565b6105a391906136f3565b90508b6002018a815481106105c857634e487b7160e01b600052603260045260246000fd5b906000526020600020015481836105df919061381d565b6105e991906136f3565b91508782101561060b5760405162461bcd60e51b81526004016102a6906136b7565b60008c6002018b8154811061063057634e487b7160e01b600052603260045260246000fd5b90600052602060002001546402540be4008e600501548461065191906137fe565b61065b91906136f3565b61066591906136f3565b9050898d6003018d8154811061068b57634e487b7160e01b600052603260045260246000fd5b9060005260206000200160008282546106a491906136db565b909155506106b4905081846136db565b8d6003018c815481106106d757634e487b7160e01b600052603260045260246000fd5b9060005260206000200160008282546106f0919061381d565b9250508190555061073b33848f6000018e8154811061071f57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b03169190612797565b604080518d8152602081018c90529081018c90526060810184905233907fb2e76ae99761dc136e598d4a629bb347eccb9532a5f8bbd72e18467c3c34cc989060800160405180910390a25090955050505050505b95945050505050565b825482516000919081146107be5760405162461bcd60e51b81526004016102a690613689565b60006107c9866121be565b905060006107df6107d988612110565b83612297565b905060008760030180548060200260200160405190810160405280929190818152602001828054801561083157602002820191906000526020600020905b81548152602001906001019080831161081d575b5050505050905060005b8481101561091f5786156108ad5787818151811061086957634e487b7160e01b600052603260045260246000fd5b602002602001015182828151811061089157634e487b7160e01b600052603260045260246000fd5b602002602001018181516108a591906136db565b90525061090d565b8781815181106108cd57634e487b7160e01b600052603260045260246000fd5b60200260200101518282815181106108f557634e487b7160e01b600052603260045260246000fd5b60200260200101818151610909919061381d565b9052505b8061091781613860565b91505061083b565b506000610987610981838b60020180548060200260200160405190810160405280929190818152602001828054801561097757602002820191906000526020600020905b815481526020019060010190808311610963575b50505050506127ff565b85612297565b905060008960010160009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156109db57600080fd5b505afa1580156109ef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a13919061350c565b905080610a2757509450610af09350505050565b600088610a3d57610a38838661381d565b610a47565b610a47858461381d565b9050848b60010160009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a9a57600080fd5b505afa158015610aae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad2919061350c565b610adc90836137fe565b610ae691906136f3565b9750505050505050505b9392505050565b6000610b048484846128ac565b50949350505050565b82548251600091908114610b335760405162461bcd60e51b81526004016102a690613689565b6001850154604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b158015610b7a57600080fd5b505afa158015610b8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb2919061350c565b905080610bf35760405162461bcd60e51b815260206004820152600f60248201526e0746f74616c537570706c79203d203608c1b60448201526064016102a6565b6000610bfe87612c10565b90506000610c0b886121be565b9050600088600301805480602002602001604051908101604052809291908181526020018280548015610c5d57602002820191906000526020600020905b815481526020019060010190808311610c49575b505050505090506000610c78610c728b612110565b84612297565b905060005b86811015610cf657898181518110610ca557634e487b7160e01b600052603260045260246000fd5b6020026020010151838281518110610ccd57634e487b7160e01b600052603260045260246000fd5b60200260200101818151610ce1919061381d565b90525080610cee81613860565b915050610c7d565b506000610d56610981848d60020180548060200260200160405190810160405280929190818152602001828054801561097757602002820191906000526020600020908154815260200190600101908083116109635750505050506127ff565b905060008767ffffffffffffffff811115610d8157634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610daa578160200160208202803683370190505b50905060005b88811015610f9a576000848e6003018381548110610dde57634e487b7160e01b600052603260045260246000fd5b906000526020600020015485610df491906137fe565b610dfe91906136f3565b90506000610e33878481518110610e2557634e487b7160e01b600052603260045260246000fd5b602002602001015183612c45565b90506402540be400610e45828b6137fe565b610e4f91906136f3565b848481518110610e6f57634e487b7160e01b600052603260045260246000fd5b6020026020010181815250506402540be4008f60050154858581518110610ea657634e487b7160e01b600052603260045260246000fd5b6020026020010151610eb891906137fe565b610ec291906136f3565b878481518110610ee257634e487b7160e01b600052603260045260246000fd5b6020026020010151610ef4919061381d565b8f6003018481548110610f1757634e487b7160e01b600052603260045260246000fd5b9060005260206000200181905550838381518110610f4557634e487b7160e01b600052603260045260246000fd5b6020026020010151878481518110610f6d57634e487b7160e01b600052603260045260246000fd5b60200260200101818151610f81919061381d565b905250829150610f92905081613860565b915050610db0565b50610ffe610ff8858e60020180548060200260200160405190810160405280929190818152602001828054801561097757602002820191906000526020600020908154815260200190600101908083116109635750505050506127ff565b86612297565b9150828761100c848361381d565b61101691906137fe565b61102091906136f3565b98506000891161104057634e487b7160e01b600052600160045260246000fd5b898911156110605760405162461bcd60e51b81526004016102a6906136b7565b60018c015460405163079cc67960e41b8152336004820152602481018b90526001600160a01b03909116906379cc679090604401600060405180830381600087803b1580156110ae57600080fd5b505af11580156110c2573d6000803e3d6000fd5b5050505060005b88811015611161578b81815181106110f157634e487b7160e01b600052603260045260246000fd5b602002602001015160001461114f5761114f338d838151811061112457634e487b7160e01b600052603260045260246000fd5b60200260200101518f600001848154811061071f57634e487b7160e01b600052603260045260246000fd5b8061115981613860565b9150506110c9565b50337f3631c28b1f9dd213e0319fb167b554d76b6c283a41143eb400a0d1adb1af17558c83856111918e8d61381d565b6040516111a194939291906135f4565b60405180910390a250505050505050509392505050565b6000610391826121be565b6000808560010160009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561121657600080fd5b505afa15801561122a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061124e919061350c565b9050600081116112925760405162461bcd60e51b815260206004820152600f60248201526e0746f74616c537570706c79203d203608c1b60448201526064016102a6565b855460018701546040516370a0823160e01b81523360048201526001600160a01b03909116906370a082319060240160206040518083038186803b1580156112d957600080fd5b505afa1580156112ed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611311919061350c565b86111561134c5760405162461bcd60e51b81526020600482015260096024820152683e2062616c616e636560b81b60448201526064016102a6565b8186111561138c5760405162461bcd60e51b815260206004820152600d60248201526c3e20746f74616c537570706c7960981b60448201526064016102a6565b8085106113cb5760405162461bcd60e51b815260206004820152600d60248201526c1d1bdad95b939bdd119bdd5b99609a1b60448201526064016102a6565b6000806113d98989896128ac565b92509050858110156113fd5760405162461bcd60e51b81526004016102a6906136b7565b6402540be40089600501548361141391906137fe565b61141d91906136f3565b61142790826136db565b89600301888154811061144a57634e487b7160e01b600052603260045260246000fd5b906000526020600020016000828254611463919061381d565b9091555050600189015460405163079cc67960e41b8152336004820152602481018a90526001600160a01b03909116906379cc679090604401600060405180830381600087803b1580156114b657600080fd5b505af11580156114ca573d6000803e3d6000fd5b505050506114f633828b6000018a8154811061071f57634e487b7160e01b600052603260045260246000fd5b60408051888152602081018a905290810182905233907f5ad056f2e28a8cec232015406b843668c1e36cda598127ec3b8c59b8c72773a09060600160405180910390a298975050505050505050565b60006064611552836121be565b61039191906136f3565b606060008460010160009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156115b057600080fd5b505afa1580156115c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e8919061350c565b9050808411156115f757600080fd5b845460008167ffffffffffffffff81111561162257634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561164b578160200160208202803683370190505b5090506116588787612c67565b935060005b84518110156117c65785818151811061168657634e487b7160e01b600052603260045260246000fd5b60200260200101518582815181106116ae57634e487b7160e01b600052603260045260246000fd5b602002602001015110156116d45760405162461bcd60e51b81526004016102a6906136b7565b8481815181106116f457634e487b7160e01b600052603260045260246000fd5b602002602001015188600301828154811061171f57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154611734919061381d565b88600301828154811061175757634e487b7160e01b600052603260045260246000fd5b90600052602060002001819055506117b43386838151811061178957634e487b7160e01b600052603260045260246000fd5b60200260200101518a600001848154811061071f57634e487b7160e01b600052603260045260246000fd5b806117be81613860565b91505061165d565b50600187015460405163079cc67960e41b8152336004820152602481018890526001600160a01b03909116906379cc679090604401600060405180830381600087803b15801561181557600080fd5b505af1158015611829573d6000803e3d6000fd5b503392507f347ad828e58cbe534d8f6b67985d791360756b18f0d95fd9f197a66cc46480ea91508690508361185e8a8861381d565b60405161186d939291906135be565b60405180910390a25050509392505050565b825482516000919081146118a55760405162461bcd60e51b81526004016102a690613689565b60008167ffffffffffffffff8111156118ce57634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156118f7578160200160208202803683370190505b509050600061190587612c10565b905060008760010160009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561195957600080fd5b505afa15801561196d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611991919061350c565b9050600061199e896121be565b905060008215611a5a57611a576107d98b6003018054806020026020016040519081016040528092919081815260200182805480156119fc57602002820191906000526020600020905b8154815260200190600101908083116119e8575b50505050508c60020180548060200260200160405190810160405280929190818152602001828054801561097757602002820191906000526020600020908154815260200190600101908083116109635750505050506127ff565b90505b60008a600301805480602002602001604051908101604052809291908181526020018280548015611aaa57602002820191906000526020600020905b815481526020019060010190808311611a96575b5050505050905060005b87811015611bf25784611b385760008b8281518110611ae357634e487b7160e01b600052603260045260246000fd5b602002602001015111611b385760405162461bcd60e51b815260206004820152601e60248201527f696e697469616c4465706f73697452657175697265416c6c546f6b656e73000060448201526064016102a6565b611ba98c6000018281548110611b5e57634e487b7160e01b600052603260045260246000fd5b9060005260206000200160009054906101000a90046001600160a01b03168c8381518110611b9c57634e487b7160e01b600052603260045260246000fd5b6020026020010151612441565b828281518110611bc957634e487b7160e01b600052603260045260246000fd5b60200260200101818151611bdd91906136db565b90525080611bea81613860565b915050611ab4565b506000611c52610981838e60020180548060200260200160405190810160405280929190818152602001828054801561097757602002820191906000526020600020908154815260200190600101908083116109635750505050506127ff565b9050828111611c7157634e487b7160e01b600052600160045260246000fd5b84611c94578151611c8b9060038e0190602085019061322e565b50809850611efa565b6000805b89811015611e7757611d14858f6003018381548110611cc757634e487b7160e01b600052603260045260246000fd5b906000526020600020015485611cdd91906137fe565b611ce791906136f3565b858381518110611d0757634e487b7160e01b600052603260045260246000fd5b6020026020010151612c45565b91506402540be400611d26838a6137fe565b611d3091906136f3565b898281518110611d5057634e487b7160e01b600052603260045260246000fd5b6020026020010181815250506402540be4008e600501548a8381518110611d8757634e487b7160e01b600052603260045260246000fd5b6020026020010151611d9991906137fe565b611da391906136f3565b848281518110611dc357634e487b7160e01b600052603260045260246000fd5b6020026020010151611dd5919061381d565b8e6003018281548110611df857634e487b7160e01b600052603260045260246000fd5b9060005260206000200181905550888181518110611e2657634e487b7160e01b600052603260045260246000fd5b6020026020010151848281518110611e4e57634e487b7160e01b600052603260045260246000fd5b60200260200101818151611e62919061381d565b90525080611e6f81613860565b915050611c98565b50611ed5610ff8848f60020180548060200260200160405190810160405280929190818152602001828054801561097757602002820191906000526020600020908154815260200190600101908083116109635750505050506127ff565b915083611ee2818461381d565b611eec90886137fe565b611ef691906136f3565b9950505b89891015611f1a5760405162461bcd60e51b81526004016102a6906136b7565b60018c01546040516340c10f1960e01b8152336004820152602481018b90526001600160a01b03909116906340c10f1990604401600060405180830381600087803b158015611f6857600080fd5b505af1158015611f7c573d6000803e3d6000fd5b50505050336001600160a01b03167f189c623b666b1b45b83d7178f39b8c087cb09774317ca2f53c2d3c3726f222a28c89848d6040516111a194939291906135f4565b600080611fcb86612110565b90506000866002018681548110611ff257634e487b7160e01b600052603260045260246000fd5b90600052602060002001548461200891906137fe565b82878151811061202857634e487b7160e01b600052603260045260246000fd5b602002602001015161203a91906136db565b9050600061204b8888888587612557565b9050600088600201878154811061207257634e487b7160e01b600052603260045260246000fd5b9060005260206000200154600183868a815181106120a057634e487b7160e01b600052603260045260246000fd5b60200260200101516120b2919061381d565b6120bc919061381d565b6120c691906136f3565b905060006402540be400828b600401546120e091906137fe565b6120ea91906136f3565b90506120f6818361381d565b9a9950505050505050505050565b606061038e8383612c67565b60606103918260030180548060200260200160405190810160405280929190818152602001828054801561216357602002820191906000526020600020905b81548152602001906001019080831161214f575b50505050508360020180548060200260200160405190810160405280929190818152602001828054801561097757602002820191906000526020600020908154815260200190600101908083116109635750505050506127ff565b6000816009015442106121d357506007015490565b81600601548260070154111561223d57816008015482600901546121f7919061381d565b6008830154612206904261381d565b8360060154846007015461221a919061381d565b61222491906137fe565b61222e91906136f3565b826006015461039191906136db565b81600801548260090154612251919061381d565b6008830154612260904261381d565b83600701548460060154612274919061381d565b61227e91906137fe565b61228891906136f3565b8260060154610391919061381d565b8151600090816122a685612e29565b9050806122b857600092505050610391565b600081816122c685886137fe565b905060005b6101008110156123f8578260005b8a5181101561233d57878b828151811061230357634e487b7160e01b600052603260045260246000fd5b602002602001015161231591906137fe565b61231f86846137fe565b61232991906136f3565b91508061233581613860565b9150506122d9565b508394508087600161234f91906136db565b61235991906137fe565b606485612366828761381d565b61237091906137fe565b61237a91906136f3565b61238491906136db565b8461238f89846137fe565b606461239b8a886137fe565b6123a591906136f3565b6123af91906136db565b6123b991906137fe565b6123c391906136f3565b935060016123d18587612c45565b116123e55783975050505050505050610391565b50806123f081613860565b9150506122cb565b5060405162461bcd60e51b815260206004820152601a60248201527f696e76617269616e7443616c63756c6174696f6e4661696c656400000000000060448201526064016102a6565b6040516370a0823160e01b815230600482015260009081906001600160a01b038516906370a082319060240160206040518083038186803b15801561248557600080fd5b505afa158015612499573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124bd919061350c565b90506124d46001600160a01b038516333086612e83565b6040516370a0823160e01b815230600482015281906001600160a01b038616906370a082319060240160206040518083038186803b15801561251557600080fd5b505afa158015612529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061254d919061350c565b610463919061381d565b6000838514156125955760405162461bcd60e51b815260206004820152600960248201526839b0b6b2aa37b5b2b760b91b60448201526064016102a6565b855480861080156125a557508085105b6125c15760405162461bcd60e51b81526004016102a690613660565b60006125cc886121be565b905060006125da83836137fe565b905060006125e88684612297565b9050600081815b8681101561267e578a8114156126045761266c565b60008c821461263a5789828151811061262d57634e487b7160e01b600052603260045260246000fd5b602002602001015161263c565b8a5b905061264881856136db565b935061265488826137fe565b61265e86856137fe565b61266891906136f3565b9250505b8061267681613860565b9150506125ef565b5061268986856137fe565b606461269585846137fe565b61269f91906137fe565b6126a991906136f3565b90506000846126b96064866137fe565b6126c391906136f3565b6126cd90846136db565b9050600084815b6101008110156127595781925086848360026126f091906137fe565b6126fa91906136db565b612704919061381d565b8561270f84806137fe565b61271991906136db565b61272391906136f3565b915060016127318484612c45565b116127475750985061078f975050505050505050565b8061275181613860565b9150506126d4565b5060405162461bcd60e51b81526020600482015260126024820152711e50d85b18dd5b185d1a5bdb91985a5b195960721b60448201526064016102a6565b6040516001600160a01b0383166024820152604481018290526127fa90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612ec1565b505050565b606060005b83518110156128a45783818151811061282d57634e487b7160e01b600052603260045260246000fd5b602002602001015183828151811061285557634e487b7160e01b600052603260045260246000fd5b602002602001015161286791906137fe565b83828151811061288757634e487b7160e01b600052603260045260246000fd5b60209081029190910101528061289c81613860565b915050612804565b509092915050565b8254600090819083106128d15760405162461bcd60e51b81526004016102a690613660565b60006128dc866121be565b905060006128e987612110565b905060006128f78284612297565b905060008860010160009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561294b57600080fd5b505afa15801561295f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612983919061350c565b61298d838a6137fe565b61299791906136f3565b6129a1908361381d565b905060006129b28a868a8786612f93565b90508360006129c08c612c10565b905060005b8c54811015612b005760008b821415612a28578487878a85815181106129fb57634e487b7160e01b600052603260045260246000fd5b6020026020010151612a0d91906137fe565b612a1791906136f3565b612a21919061381d565b9050612a9b565b8686898481518110612a4a57634e487b7160e01b600052603260045260246000fd5b6020026020010151612a5c91906137fe565b612a6691906136f3565b888381518110612a8657634e487b7160e01b600052603260045260246000fd5b6020026020010151612a98919061381d565b90505b6402540be400612aab82856137fe565b612ab591906136f3565b848381518110612ad557634e487b7160e01b600052603260045260246000fd5b60200260200101818151612ae9919061381d565b905250819050612af881613860565b9150506129c5565b50612b0e8c888c8588612f93565b828b81518110612b2e57634e487b7160e01b600052603260045260246000fd5b6020026020010151612b40919061381d565b98508b6002018a81548110612b6557634e487b7160e01b600052603260045260246000fd5b906000526020600020015460018a612b7d919061381d565b612b8791906136f3565b9850888c6002018b81548110612bad57634e487b7160e01b600052603260045260246000fd5b906000526020600020015484888d81518110612bd957634e487b7160e01b600052603260045260246000fd5b6020026020010151612beb919061381d565b612bf591906136f3565b612bff919061381d565b975050505050505050935093915050565b8054600090612c2060018261381d565b612c2b9060046137fe565b818460040154612c3b91906137fe565b610af091906136f3565b6000818311612c5d57612c58838361381d565b61038e565b61038e828461381d565b606060008360010160009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612cbb57600080fd5b505afa158015612ccf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cf3919061350c565b905080831115612d455760405162461bcd60e51b815260206004820152601a60248201527f43616e6e6f742065786365656420746f74616c20737570706c7900000000000060448201526064016102a6565b835460009067ffffffffffffffff811115612d7057634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612d99578160200160208202803683370190505b50905060005b8554811015610b04578285876003018381548110612dcd57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154612de291906137fe565b612dec91906136f3565b828281518110612e0c57634e487b7160e01b600052603260045260246000fd5b602090810291909101015280612e2181613860565b915050612d9f565b6000805b8251811015612e7d57828181518110612e5657634e487b7160e01b600052603260045260246000fd5b602002602001015182612e6991906136db565b915080612e7581613860565b915050612e2d565b50919050565b6040516001600160a01b0380851660248301528316604482015260648101829052612ebb9085906323b872dd60e01b906084016127c3565b50505050565b6000612f16826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166131239092919063ffffffff16565b8051909150156127fa5780806020019051810190612f34919061332c565b6127fa5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016102a6565b8454600090808510612fb557634e487b7160e01b600052600160045260246000fd5b6000612fc182886137fe565b90508360008080805b8681101561304a578a811415612fdf57613038565b898181518110612fff57634e487b7160e01b600052603260045260246000fd5b60200260200101519250828461301591906136db565b935061302187846137fe565b61302b8a876137fe565b61303591906136f3565b94505b8061304281613860565b915050612fca565b5061305586866137fe565b60646130618a876137fe565b61306b91906137fe565b61307591906136f3565b935060008561308560648b6137fe565b61308f91906136f3565b61309990856136db565b90508860005b6101008110156123f8578193508a838360026130bb91906137fe565b6130c591906136db565b6130cf919061381d565b876130da84806137fe565b6130e491906136db565b6130ee91906136f3565b915060016130fc8584612c45565b116131115750975061078f9650505050505050565b8061311b81613860565b91505061309f565b6060610463848460008585843b61317c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102a6565b600080866001600160a01b03168587604051613198919061355e565b60006040518083038185875af1925050503d80600081146131d5576040519150601f19603f3d011682016040523d82523d6000602084013e6131da565b606091505b50915091506131ea8282866131f5565b979650505050505050565b60608315613204575081610af0565b8251156132145782518084602001fd5b8160405162461bcd60e51b81526004016102a6919061362d565b828054828255906000526020600020908101928215613269579160200282015b8281111561326957825182559160200191906001019061324e565b50613275929150613279565b5090565b5b80821115613275576000815560010161327a565b600082601f83011261329e578081fd5b8135602067ffffffffffffffff808311156132bb576132bb613891565b8260051b604051601f19603f830116810181811084821117156132e0576132e0613891565b604052848152838101925086840182880185018910156132fe578687fd5b8692505b85831015613320578035845292840192600192909201918401613302565b50979650505050505050565b60006020828403121561333d578081fd5b8151610af0816138a7565b600060208284031215613359578081fd5b5035919050565b600080600060608486031215613374578182fd5b83359250602084013567ffffffffffffffff811115613391578283fd5b61339d8682870161328e565b92505060408401356133ae816138a7565b809150509250925092565b6000806000606084860312156133cd578283fd5b83359250602084013567ffffffffffffffff8111156133ea578283fd5b6133f68682870161328e565b925050604084013590509250925092565b60008060408385031215613419578182fd5b50508035926020909101359150565b60008060006060848603121561343c578283fd5b8335925060208401359150604084013567ffffffffffffffff811115613460578182fd5b61346c8682870161328e565b9150509250925092565b60008060006060848603121561348a578283fd5b505081359360208301359350604090920135919050565b600080600080608085870312156134b6578081fd5b5050823594602084013594506040840135936060013592509050565b600080600080600060a086880312156134e9578081fd5b505083359560208501359550604085013594606081013594506080013592509050565b60006020828403121561351d578081fd5b5051919050565b6000815180845260208085019450808401835b8381101561355357815187529582019590820190600101613537565b509495945050505050565b60008251613570818460208701613834565b9190910192915050565b6020808252825182820181905260009190848201906040850190845b818110156135b257835183529284019291840191600101613596565b50909695505050505050565b6060815260006135d16060830186613524565b82810360208401526135e38186613524565b915050826040830152949350505050565b6080815260006136076080830187613524565b82810360208401526136198187613524565b604084019590955250506060015292915050565b602081526000825180602084015261364c816040850160208701613834565b601f01601f19169190910160400192915050565b6020808252600f908201526e696e6465784f75744f6652616e676560881b604082015260600190565b6020808252601490820152730d2dcecc2d8d2c882dadeeadce8e698cadccee8d60631b604082015260600190565b6020808252600a90820152693e20736c69707061676560b01b604082015260600190565b600082198211156136ee576136ee61387b565b500190565b60008261370e57634e487b7160e01b81526012600452602481fd5b500490565b600181815b8085111561374e5781600019048211156137345761373461387b565b8085161561374157918102915b93841c9390800290613718565b509250929050565b600061038e838360008261376c57506001610391565b8161377957506000610391565b816001811461378f5760028114613799576137b5565b6001915050610391565b60ff8411156137aa576137aa61387b565b50506001821b610391565b5060208310610133831016604e8410600b84101617156137d8575081810a610391565b6137e28383613713565b80600019048211156137f6576137f661387b565b029392505050565b60008160001904831182151516156138185761381861387b565b500290565b60008282101561382f5761382f61387b565b500390565b60005b8381101561384f578181015183820152602001613837565b83811115612ebb5750506000910152565b60006000198214156138745761387461387b565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b80151581146138b557600080fd5b5056fea264697066735822122025471ed66f323979164289b6827ff66f8f90f93f94dc0bc6cd7392eba60528ae64736f6c63430008040033
Deployed Bytecode
0x73b75380dc6a3331aed107a788017e251d12f79ad8301460806040526004361061010a5760003560e01c8063b9510fc8116100a1578063d73792a911610070578063d73792a914610231578063e42f75fa1461023d578063ec623a1e1461025d578063f94eed871461027057600080fd5b8063b9510fc8146101e1578063c20aace8146101f4578063d011f918146101fc578063d0b1a0051461020457600080fd5b80634ddd2918116100dd5780634ddd29181461017b578063576b97351461018e5780637461cf1b146101ae5780638ce65d8e146101c157600080fd5b80630a1368cd1461010f57806337ac5bea146101355780633a8d10bd1461014857806345b69ab714610168575b600080fd5b61012261011d366004613407565b610283565b6040519081526020015b60405180910390f35b610122610143366004613348565b610397565b81801561015457600080fd5b506101226101633660046134d2565b61046b565b610122610176366004613360565b610798565b610122610189366004613476565b610af7565b81801561019a57600080fd5b506101226101a93660046133b9565b610b0d565b6101226101bc366004613348565b6111b8565b8180156101cd57600080fd5b506101226101dc3660046134a1565b6111c3565b6101226101ef366004613348565b611545565b610122601281565b610122606481565b81801561021057600080fd5b5061022461021f366004613428565b61155c565b60405161012c919061357a565b6101226402540be40081565b81801561024957600080fd5b506101226102583660046133b9565b61187f565b61012261026b3660046134a1565b611fbf565b61022461027e366004613407565b612104565b815460009082106102af5760405162461bcd60e51b81526004016102a690613660565b60405180910390fd5b8260030182815481106102d257634e487b7160e01b600052603260045260246000fd5b906000526020600020015483600001838154811061030057634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561034c57600080fd5b505afa158015610360573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610384919061350c565b61038e919061381d565b90505b92915050565b6000806103b46103a684612110565b6103af856121be565b612297565b905060008360010160009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561040857600080fd5b505afa15801561041c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610440919061350c565b90508061044f6012600a613756565b61045990846137fe565b61046391906136f3565b949350505050565b60008086600001868154811061049157634e487b7160e01b600052603260045260246000fd5b60009182526020822001546001600160a01b031691506104b088612110565b90506104bc8286612441565b945060008860020188815481106104e357634e487b7160e01b600052603260045260246000fd5b9060005260206000200154866104f991906137fe565b82898151811061051957634e487b7160e01b600052603260045260246000fd5b602002602001015161052b91906136db565b9050600061053c8a8a8a8587612557565b90506000600182858b8151811061056357634e487b7160e01b600052603260045260246000fd5b6020026020010151610575919061381d565b61057f919061381d565b905060006402540be4008c600401548361059991906137fe565b6105a391906136f3565b90508b6002018a815481106105c857634e487b7160e01b600052603260045260246000fd5b906000526020600020015481836105df919061381d565b6105e991906136f3565b91508782101561060b5760405162461bcd60e51b81526004016102a6906136b7565b60008c6002018b8154811061063057634e487b7160e01b600052603260045260246000fd5b90600052602060002001546402540be4008e600501548461065191906137fe565b61065b91906136f3565b61066591906136f3565b9050898d6003018d8154811061068b57634e487b7160e01b600052603260045260246000fd5b9060005260206000200160008282546106a491906136db565b909155506106b4905081846136db565b8d6003018c815481106106d757634e487b7160e01b600052603260045260246000fd5b9060005260206000200160008282546106f0919061381d565b9250508190555061073b33848f6000018e8154811061071f57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b03169190612797565b604080518d8152602081018c90529081018c90526060810184905233907fb2e76ae99761dc136e598d4a629bb347eccb9532a5f8bbd72e18467c3c34cc989060800160405180910390a25090955050505050505b95945050505050565b825482516000919081146107be5760405162461bcd60e51b81526004016102a690613689565b60006107c9866121be565b905060006107df6107d988612110565b83612297565b905060008760030180548060200260200160405190810160405280929190818152602001828054801561083157602002820191906000526020600020905b81548152602001906001019080831161081d575b5050505050905060005b8481101561091f5786156108ad5787818151811061086957634e487b7160e01b600052603260045260246000fd5b602002602001015182828151811061089157634e487b7160e01b600052603260045260246000fd5b602002602001018181516108a591906136db565b90525061090d565b8781815181106108cd57634e487b7160e01b600052603260045260246000fd5b60200260200101518282815181106108f557634e487b7160e01b600052603260045260246000fd5b60200260200101818151610909919061381d565b9052505b8061091781613860565b91505061083b565b506000610987610981838b60020180548060200260200160405190810160405280929190818152602001828054801561097757602002820191906000526020600020905b815481526020019060010190808311610963575b50505050506127ff565b85612297565b905060008960010160009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156109db57600080fd5b505afa1580156109ef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a13919061350c565b905080610a2757509450610af09350505050565b600088610a3d57610a38838661381d565b610a47565b610a47858461381d565b9050848b60010160009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a9a57600080fd5b505afa158015610aae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad2919061350c565b610adc90836137fe565b610ae691906136f3565b9750505050505050505b9392505050565b6000610b048484846128ac565b50949350505050565b82548251600091908114610b335760405162461bcd60e51b81526004016102a690613689565b6001850154604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b158015610b7a57600080fd5b505afa158015610b8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb2919061350c565b905080610bf35760405162461bcd60e51b815260206004820152600f60248201526e0746f74616c537570706c79203d203608c1b60448201526064016102a6565b6000610bfe87612c10565b90506000610c0b886121be565b9050600088600301805480602002602001604051908101604052809291908181526020018280548015610c5d57602002820191906000526020600020905b815481526020019060010190808311610c49575b505050505090506000610c78610c728b612110565b84612297565b905060005b86811015610cf657898181518110610ca557634e487b7160e01b600052603260045260246000fd5b6020026020010151838281518110610ccd57634e487b7160e01b600052603260045260246000fd5b60200260200101818151610ce1919061381d565b90525080610cee81613860565b915050610c7d565b506000610d56610981848d60020180548060200260200160405190810160405280929190818152602001828054801561097757602002820191906000526020600020908154815260200190600101908083116109635750505050506127ff565b905060008767ffffffffffffffff811115610d8157634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610daa578160200160208202803683370190505b50905060005b88811015610f9a576000848e6003018381548110610dde57634e487b7160e01b600052603260045260246000fd5b906000526020600020015485610df491906137fe565b610dfe91906136f3565b90506000610e33878481518110610e2557634e487b7160e01b600052603260045260246000fd5b602002602001015183612c45565b90506402540be400610e45828b6137fe565b610e4f91906136f3565b848481518110610e6f57634e487b7160e01b600052603260045260246000fd5b6020026020010181815250506402540be4008f60050154858581518110610ea657634e487b7160e01b600052603260045260246000fd5b6020026020010151610eb891906137fe565b610ec291906136f3565b878481518110610ee257634e487b7160e01b600052603260045260246000fd5b6020026020010151610ef4919061381d565b8f6003018481548110610f1757634e487b7160e01b600052603260045260246000fd5b9060005260206000200181905550838381518110610f4557634e487b7160e01b600052603260045260246000fd5b6020026020010151878481518110610f6d57634e487b7160e01b600052603260045260246000fd5b60200260200101818151610f81919061381d565b905250829150610f92905081613860565b915050610db0565b50610ffe610ff8858e60020180548060200260200160405190810160405280929190818152602001828054801561097757602002820191906000526020600020908154815260200190600101908083116109635750505050506127ff565b86612297565b9150828761100c848361381d565b61101691906137fe565b61102091906136f3565b98506000891161104057634e487b7160e01b600052600160045260246000fd5b898911156110605760405162461bcd60e51b81526004016102a6906136b7565b60018c015460405163079cc67960e41b8152336004820152602481018b90526001600160a01b03909116906379cc679090604401600060405180830381600087803b1580156110ae57600080fd5b505af11580156110c2573d6000803e3d6000fd5b5050505060005b88811015611161578b81815181106110f157634e487b7160e01b600052603260045260246000fd5b602002602001015160001461114f5761114f338d838151811061112457634e487b7160e01b600052603260045260246000fd5b60200260200101518f600001848154811061071f57634e487b7160e01b600052603260045260246000fd5b8061115981613860565b9150506110c9565b50337f3631c28b1f9dd213e0319fb167b554d76b6c283a41143eb400a0d1adb1af17558c83856111918e8d61381d565b6040516111a194939291906135f4565b60405180910390a250505050505050509392505050565b6000610391826121be565b6000808560010160009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561121657600080fd5b505afa15801561122a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061124e919061350c565b9050600081116112925760405162461bcd60e51b815260206004820152600f60248201526e0746f74616c537570706c79203d203608c1b60448201526064016102a6565b855460018701546040516370a0823160e01b81523360048201526001600160a01b03909116906370a082319060240160206040518083038186803b1580156112d957600080fd5b505afa1580156112ed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611311919061350c565b86111561134c5760405162461bcd60e51b81526020600482015260096024820152683e2062616c616e636560b81b60448201526064016102a6565b8186111561138c5760405162461bcd60e51b815260206004820152600d60248201526c3e20746f74616c537570706c7960981b60448201526064016102a6565b8085106113cb5760405162461bcd60e51b815260206004820152600d60248201526c1d1bdad95b939bdd119bdd5b99609a1b60448201526064016102a6565b6000806113d98989896128ac565b92509050858110156113fd5760405162461bcd60e51b81526004016102a6906136b7565b6402540be40089600501548361141391906137fe565b61141d91906136f3565b61142790826136db565b89600301888154811061144a57634e487b7160e01b600052603260045260246000fd5b906000526020600020016000828254611463919061381d565b9091555050600189015460405163079cc67960e41b8152336004820152602481018a90526001600160a01b03909116906379cc679090604401600060405180830381600087803b1580156114b657600080fd5b505af11580156114ca573d6000803e3d6000fd5b505050506114f633828b6000018a8154811061071f57634e487b7160e01b600052603260045260246000fd5b60408051888152602081018a905290810182905233907f5ad056f2e28a8cec232015406b843668c1e36cda598127ec3b8c59b8c72773a09060600160405180910390a298975050505050505050565b60006064611552836121be565b61039191906136f3565b606060008460010160009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156115b057600080fd5b505afa1580156115c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e8919061350c565b9050808411156115f757600080fd5b845460008167ffffffffffffffff81111561162257634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561164b578160200160208202803683370190505b5090506116588787612c67565b935060005b84518110156117c65785818151811061168657634e487b7160e01b600052603260045260246000fd5b60200260200101518582815181106116ae57634e487b7160e01b600052603260045260246000fd5b602002602001015110156116d45760405162461bcd60e51b81526004016102a6906136b7565b8481815181106116f457634e487b7160e01b600052603260045260246000fd5b602002602001015188600301828154811061171f57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154611734919061381d565b88600301828154811061175757634e487b7160e01b600052603260045260246000fd5b90600052602060002001819055506117b43386838151811061178957634e487b7160e01b600052603260045260246000fd5b60200260200101518a600001848154811061071f57634e487b7160e01b600052603260045260246000fd5b806117be81613860565b91505061165d565b50600187015460405163079cc67960e41b8152336004820152602481018890526001600160a01b03909116906379cc679090604401600060405180830381600087803b15801561181557600080fd5b505af1158015611829573d6000803e3d6000fd5b503392507f347ad828e58cbe534d8f6b67985d791360756b18f0d95fd9f197a66cc46480ea91508690508361185e8a8861381d565b60405161186d939291906135be565b60405180910390a25050509392505050565b825482516000919081146118a55760405162461bcd60e51b81526004016102a690613689565b60008167ffffffffffffffff8111156118ce57634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156118f7578160200160208202803683370190505b509050600061190587612c10565b905060008760010160009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561195957600080fd5b505afa15801561196d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611991919061350c565b9050600061199e896121be565b905060008215611a5a57611a576107d98b6003018054806020026020016040519081016040528092919081815260200182805480156119fc57602002820191906000526020600020905b8154815260200190600101908083116119e8575b50505050508c60020180548060200260200160405190810160405280929190818152602001828054801561097757602002820191906000526020600020908154815260200190600101908083116109635750505050506127ff565b90505b60008a600301805480602002602001604051908101604052809291908181526020018280548015611aaa57602002820191906000526020600020905b815481526020019060010190808311611a96575b5050505050905060005b87811015611bf25784611b385760008b8281518110611ae357634e487b7160e01b600052603260045260246000fd5b602002602001015111611b385760405162461bcd60e51b815260206004820152601e60248201527f696e697469616c4465706f73697452657175697265416c6c546f6b656e73000060448201526064016102a6565b611ba98c6000018281548110611b5e57634e487b7160e01b600052603260045260246000fd5b9060005260206000200160009054906101000a90046001600160a01b03168c8381518110611b9c57634e487b7160e01b600052603260045260246000fd5b6020026020010151612441565b828281518110611bc957634e487b7160e01b600052603260045260246000fd5b60200260200101818151611bdd91906136db565b90525080611bea81613860565b915050611ab4565b506000611c52610981838e60020180548060200260200160405190810160405280929190818152602001828054801561097757602002820191906000526020600020908154815260200190600101908083116109635750505050506127ff565b9050828111611c7157634e487b7160e01b600052600160045260246000fd5b84611c94578151611c8b9060038e0190602085019061322e565b50809850611efa565b6000805b89811015611e7757611d14858f6003018381548110611cc757634e487b7160e01b600052603260045260246000fd5b906000526020600020015485611cdd91906137fe565b611ce791906136f3565b858381518110611d0757634e487b7160e01b600052603260045260246000fd5b6020026020010151612c45565b91506402540be400611d26838a6137fe565b611d3091906136f3565b898281518110611d5057634e487b7160e01b600052603260045260246000fd5b6020026020010181815250506402540be4008e600501548a8381518110611d8757634e487b7160e01b600052603260045260246000fd5b6020026020010151611d9991906137fe565b611da391906136f3565b848281518110611dc357634e487b7160e01b600052603260045260246000fd5b6020026020010151611dd5919061381d565b8e6003018281548110611df857634e487b7160e01b600052603260045260246000fd5b9060005260206000200181905550888181518110611e2657634e487b7160e01b600052603260045260246000fd5b6020026020010151848281518110611e4e57634e487b7160e01b600052603260045260246000fd5b60200260200101818151611e62919061381d565b90525080611e6f81613860565b915050611c98565b50611ed5610ff8848f60020180548060200260200160405190810160405280929190818152602001828054801561097757602002820191906000526020600020908154815260200190600101908083116109635750505050506127ff565b915083611ee2818461381d565b611eec90886137fe565b611ef691906136f3565b9950505b89891015611f1a5760405162461bcd60e51b81526004016102a6906136b7565b60018c01546040516340c10f1960e01b8152336004820152602481018b90526001600160a01b03909116906340c10f1990604401600060405180830381600087803b158015611f6857600080fd5b505af1158015611f7c573d6000803e3d6000fd5b50505050336001600160a01b03167f189c623b666b1b45b83d7178f39b8c087cb09774317ca2f53c2d3c3726f222a28c89848d6040516111a194939291906135f4565b600080611fcb86612110565b90506000866002018681548110611ff257634e487b7160e01b600052603260045260246000fd5b90600052602060002001548461200891906137fe565b82878151811061202857634e487b7160e01b600052603260045260246000fd5b602002602001015161203a91906136db565b9050600061204b8888888587612557565b9050600088600201878154811061207257634e487b7160e01b600052603260045260246000fd5b9060005260206000200154600183868a815181106120a057634e487b7160e01b600052603260045260246000fd5b60200260200101516120b2919061381d565b6120bc919061381d565b6120c691906136f3565b905060006402540be400828b600401546120e091906137fe565b6120ea91906136f3565b90506120f6818361381d565b9a9950505050505050505050565b606061038e8383612c67565b60606103918260030180548060200260200160405190810160405280929190818152602001828054801561216357602002820191906000526020600020905b81548152602001906001019080831161214f575b50505050508360020180548060200260200160405190810160405280929190818152602001828054801561097757602002820191906000526020600020908154815260200190600101908083116109635750505050506127ff565b6000816009015442106121d357506007015490565b81600601548260070154111561223d57816008015482600901546121f7919061381d565b6008830154612206904261381d565b8360060154846007015461221a919061381d565b61222491906137fe565b61222e91906136f3565b826006015461039191906136db565b81600801548260090154612251919061381d565b6008830154612260904261381d565b83600701548460060154612274919061381d565b61227e91906137fe565b61228891906136f3565b8260060154610391919061381d565b8151600090816122a685612e29565b9050806122b857600092505050610391565b600081816122c685886137fe565b905060005b6101008110156123f8578260005b8a5181101561233d57878b828151811061230357634e487b7160e01b600052603260045260246000fd5b602002602001015161231591906137fe565b61231f86846137fe565b61232991906136f3565b91508061233581613860565b9150506122d9565b508394508087600161234f91906136db565b61235991906137fe565b606485612366828761381d565b61237091906137fe565b61237a91906136f3565b61238491906136db565b8461238f89846137fe565b606461239b8a886137fe565b6123a591906136f3565b6123af91906136db565b6123b991906137fe565b6123c391906136f3565b935060016123d18587612c45565b116123e55783975050505050505050610391565b50806123f081613860565b9150506122cb565b5060405162461bcd60e51b815260206004820152601a60248201527f696e76617269616e7443616c63756c6174696f6e4661696c656400000000000060448201526064016102a6565b6040516370a0823160e01b815230600482015260009081906001600160a01b038516906370a082319060240160206040518083038186803b15801561248557600080fd5b505afa158015612499573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124bd919061350c565b90506124d46001600160a01b038516333086612e83565b6040516370a0823160e01b815230600482015281906001600160a01b038616906370a082319060240160206040518083038186803b15801561251557600080fd5b505afa158015612529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061254d919061350c565b610463919061381d565b6000838514156125955760405162461bcd60e51b815260206004820152600960248201526839b0b6b2aa37b5b2b760b91b60448201526064016102a6565b855480861080156125a557508085105b6125c15760405162461bcd60e51b81526004016102a690613660565b60006125cc886121be565b905060006125da83836137fe565b905060006125e88684612297565b9050600081815b8681101561267e578a8114156126045761266c565b60008c821461263a5789828151811061262d57634e487b7160e01b600052603260045260246000fd5b602002602001015161263c565b8a5b905061264881856136db565b935061265488826137fe565b61265e86856137fe565b61266891906136f3565b9250505b8061267681613860565b9150506125ef565b5061268986856137fe565b606461269585846137fe565b61269f91906137fe565b6126a991906136f3565b90506000846126b96064866137fe565b6126c391906136f3565b6126cd90846136db565b9050600084815b6101008110156127595781925086848360026126f091906137fe565b6126fa91906136db565b612704919061381d565b8561270f84806137fe565b61271991906136db565b61272391906136f3565b915060016127318484612c45565b116127475750985061078f975050505050505050565b8061275181613860565b9150506126d4565b5060405162461bcd60e51b81526020600482015260126024820152711e50d85b18dd5b185d1a5bdb91985a5b195960721b60448201526064016102a6565b6040516001600160a01b0383166024820152604481018290526127fa90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612ec1565b505050565b606060005b83518110156128a45783818151811061282d57634e487b7160e01b600052603260045260246000fd5b602002602001015183828151811061285557634e487b7160e01b600052603260045260246000fd5b602002602001015161286791906137fe565b83828151811061288757634e487b7160e01b600052603260045260246000fd5b60209081029190910101528061289c81613860565b915050612804565b509092915050565b8254600090819083106128d15760405162461bcd60e51b81526004016102a690613660565b60006128dc866121be565b905060006128e987612110565b905060006128f78284612297565b905060008860010160009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561294b57600080fd5b505afa15801561295f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612983919061350c565b61298d838a6137fe565b61299791906136f3565b6129a1908361381d565b905060006129b28a868a8786612f93565b90508360006129c08c612c10565b905060005b8c54811015612b005760008b821415612a28578487878a85815181106129fb57634e487b7160e01b600052603260045260246000fd5b6020026020010151612a0d91906137fe565b612a1791906136f3565b612a21919061381d565b9050612a9b565b8686898481518110612a4a57634e487b7160e01b600052603260045260246000fd5b6020026020010151612a5c91906137fe565b612a6691906136f3565b888381518110612a8657634e487b7160e01b600052603260045260246000fd5b6020026020010151612a98919061381d565b90505b6402540be400612aab82856137fe565b612ab591906136f3565b848381518110612ad557634e487b7160e01b600052603260045260246000fd5b60200260200101818151612ae9919061381d565b905250819050612af881613860565b9150506129c5565b50612b0e8c888c8588612f93565b828b81518110612b2e57634e487b7160e01b600052603260045260246000fd5b6020026020010151612b40919061381d565b98508b6002018a81548110612b6557634e487b7160e01b600052603260045260246000fd5b906000526020600020015460018a612b7d919061381d565b612b8791906136f3565b9850888c6002018b81548110612bad57634e487b7160e01b600052603260045260246000fd5b906000526020600020015484888d81518110612bd957634e487b7160e01b600052603260045260246000fd5b6020026020010151612beb919061381d565b612bf591906136f3565b612bff919061381d565b975050505050505050935093915050565b8054600090612c2060018261381d565b612c2b9060046137fe565b818460040154612c3b91906137fe565b610af091906136f3565b6000818311612c5d57612c58838361381d565b61038e565b61038e828461381d565b606060008360010160009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612cbb57600080fd5b505afa158015612ccf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cf3919061350c565b905080831115612d455760405162461bcd60e51b815260206004820152601a60248201527f43616e6e6f742065786365656420746f74616c20737570706c7900000000000060448201526064016102a6565b835460009067ffffffffffffffff811115612d7057634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612d99578160200160208202803683370190505b50905060005b8554811015610b04578285876003018381548110612dcd57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154612de291906137fe565b612dec91906136f3565b828281518110612e0c57634e487b7160e01b600052603260045260246000fd5b602090810291909101015280612e2181613860565b915050612d9f565b6000805b8251811015612e7d57828181518110612e5657634e487b7160e01b600052603260045260246000fd5b602002602001015182612e6991906136db565b915080612e7581613860565b915050612e2d565b50919050565b6040516001600160a01b0380851660248301528316604482015260648101829052612ebb9085906323b872dd60e01b906084016127c3565b50505050565b6000612f16826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166131239092919063ffffffff16565b8051909150156127fa5780806020019051810190612f34919061332c565b6127fa5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016102a6565b8454600090808510612fb557634e487b7160e01b600052600160045260246000fd5b6000612fc182886137fe565b90508360008080805b8681101561304a578a811415612fdf57613038565b898181518110612fff57634e487b7160e01b600052603260045260246000fd5b60200260200101519250828461301591906136db565b935061302187846137fe565b61302b8a876137fe565b61303591906136f3565b94505b8061304281613860565b915050612fca565b5061305586866137fe565b60646130618a876137fe565b61306b91906137fe565b61307591906136f3565b935060008561308560648b6137fe565b61308f91906136f3565b61309990856136db565b90508860005b6101008110156123f8578193508a838360026130bb91906137fe565b6130c591906136db565b6130cf919061381d565b876130da84806137fe565b6130e491906136db565b6130ee91906136f3565b915060016130fc8584612c45565b116131115750975061078f9650505050505050565b8061311b81613860565b91505061309f565b6060610463848460008585843b61317c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016102a6565b600080866001600160a01b03168587604051613198919061355e565b60006040518083038185875af1925050503d80600081146131d5576040519150601f19603f3d011682016040523d82523d6000602084013e6131da565b606091505b50915091506131ea8282866131f5565b979650505050505050565b60608315613204575081610af0565b8251156132145782518084602001fd5b8160405162461bcd60e51b81526004016102a6919061362d565b828054828255906000526020600020908101928215613269579160200282015b8281111561326957825182559160200191906001019061324e565b50613275929150613279565b5090565b5b80821115613275576000815560010161327a565b600082601f83011261329e578081fd5b8135602067ffffffffffffffff808311156132bb576132bb613891565b8260051b604051601f19603f830116810181811084821117156132e0576132e0613891565b604052848152838101925086840182880185018910156132fe578687fd5b8692505b85831015613320578035845292840192600192909201918401613302565b50979650505050505050565b60006020828403121561333d578081fd5b8151610af0816138a7565b600060208284031215613359578081fd5b5035919050565b600080600060608486031215613374578182fd5b83359250602084013567ffffffffffffffff811115613391578283fd5b61339d8682870161328e565b92505060408401356133ae816138a7565b809150509250925092565b6000806000606084860312156133cd578283fd5b83359250602084013567ffffffffffffffff8111156133ea578283fd5b6133f68682870161328e565b925050604084013590509250925092565b60008060408385031215613419578182fd5b50508035926020909101359150565b60008060006060848603121561343c578283fd5b8335925060208401359150604084013567ffffffffffffffff811115613460578182fd5b61346c8682870161328e565b9150509250925092565b60008060006060848603121561348a578283fd5b505081359360208301359350604090920135919050565b600080600080608085870312156134b6578081fd5b5050823594602084013594506040840135936060013592509050565b600080600080600060a086880312156134e9578081fd5b505083359560208501359550604085013594606081013594506080013592509050565b60006020828403121561351d578081fd5b5051919050565b6000815180845260208085019450808401835b8381101561355357815187529582019590820190600101613537565b509495945050505050565b60008251613570818460208701613834565b9190910192915050565b6020808252825182820181905260009190848201906040850190845b818110156135b257835183529284019291840191600101613596565b50909695505050505050565b6060815260006135d16060830186613524565b82810360208401526135e38186613524565b915050826040830152949350505050565b6080815260006136076080830187613524565b82810360208401526136198187613524565b604084019590955250506060015292915050565b602081526000825180602084015261364c816040850160208701613834565b601f01601f19169190910160400192915050565b6020808252600f908201526e696e6465784f75744f6652616e676560881b604082015260600190565b6020808252601490820152730d2dcecc2d8d2c882dadeeadce8e698cadccee8d60631b604082015260600190565b6020808252600a90820152693e20736c69707061676560b01b604082015260600190565b600082198211156136ee576136ee61387b565b500190565b60008261370e57634e487b7160e01b81526012600452602481fd5b500490565b600181815b8085111561374e5781600019048211156137345761373461387b565b8085161561374157918102915b93841c9390800290613718565b509250929050565b600061038e838360008261376c57506001610391565b8161377957506000610391565b816001811461378f5760028114613799576137b5565b6001915050610391565b60ff8411156137aa576137aa61387b565b50506001821b610391565b5060208310610133831016604e8410600b84101617156137d8575081810a610391565b6137e28383613713565b80600019048211156137f6576137f661387b565b029392505050565b60008160001904831182151516156138185761381861387b565b500290565b60008282101561382f5761382f61387b565b500390565b60005b8381101561384f578181015183820152602001613837565b83811115612ebb5750506000910152565b60006000198214156138745761387461387b565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b80151581146138b557600080fd5b5056fea264697066735822122025471ed66f323979164289b6827ff66f8f90f93f94dc0bc6cd7392eba60528ae64736f6c63430008040033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in GLMR
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.