文件 1 的 6:Address.sol
pragma solidity ^0.7.5;
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly { size := extcodesize(account) }
return size > 0;
}
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");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return _functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
function addressToString(address _address) internal pure returns(string memory) {
bytes32 _bytes = bytes32(uint256(_address));
bytes memory HEX = "0123456789abcdef";
bytes memory _addr = new bytes(42);
_addr[0] = '0';
_addr[1] = 'x';
for(uint256 i = 0; i < 20; i++) {
_addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];
_addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];
}
return string(_addr);
}
}
文件 2 的 6:Bond.sol
import "./libraries/SafeMath.sol";
import "./libraries/FixedPoint.sol";
import "./libraries/Address.sol";
import "./interface/IERC20.sol";
interface ITreasury {
function transferToBond(uint256 _amount) external;
function valueOfToken(address _token, uint256 _amount) external view returns (uint256 value_);
function ATLAS() external view returns (address);
}
interface IUniswapV2Router02 {
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
function WETH() external pure returns (address);
}
pragma solidity ^0.7.5;
contract AtlasBonding {
using FixedPoint for *;
using SafeMath for uint256;
modifier onlyOwner() {
require(owner == msg.sender, "Ownable: caller is not the owner");
_;
}
event BondCreated(uint256 deposit, uint256 payout, uint256 expires);
event BondRedeemed(address recipient, uint256 payout, uint256 remaining);
event BondPriceChanged(uint256 internalPrice, uint256 debtRatio);
address public owner;
IERC20 public constant WETH = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
IERC20 public immutable ATLAS;
IERC20 public immutable wsATLAS;
ITreasury public immutable treasury;
IUniswapV2Router02 public immutable uniswapV2Router;
uint256 public totalPrincipalBonded;
uint256 public totalPayoutGiven;
uint256 public totalDebt;
uint256 public lastDecay;
Terms public terms;
mapping(address => Bond) public bondInfo;
struct Terms {
uint256 controlVariable;
uint256 vestingTerm;
uint256 minimumPrice;
uint256 maxPayout;
uint256 maxDebt;
}
struct Bond {
uint256 payout;
uint256 vesting;
uint256 lastBlockTimestamp;
uint256 truePricePaid;
}
constructor(address _treasury, address _wsATLAS) {
treasury = ITreasury(_treasury);
ATLAS = IERC20(ITreasury(_treasury).ATLAS());
wsATLAS = IERC20(_wsATLAS);
owner = msg.sender;
IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
uniswapV2Router = _uniswapV2Router;
}
function initializeBond(
uint256 _controlVariable,
uint256 _vestingTerm,
uint256 _minimumPrice,
uint256 _maxPayout,
uint256 _maxDebt,
uint256 _initialDebt
) external onlyOwner {
require(currentDebt() == 0, "Debt must be 0 for initialization");
WETH.approve(address(uniswapV2Router), type(uint256).max);
terms = Terms({
controlVariable: _controlVariable,
vestingTerm: _vestingTerm,
minimumPrice: _minimumPrice,
maxPayout: _maxPayout,
maxDebt: _maxDebt
});
totalDebt = _initialDebt;
lastDecay = block.timestamp;
}
function transferOwnership(address newOwner) external virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
owner = newOwner;
}
enum PARAMETER {
VESTING,
PAYOUT,
DEBT
}
function setBondTerms(PARAMETER _parameter, uint256 _input) external onlyOwner {
if (_parameter == PARAMETER.VESTING) {
require(_input >= 129600, "Vesting must be longer than 36 hours");
terms.vestingTerm = _input;
} else if (_parameter == PARAMETER.PAYOUT) {
terms.maxPayout = _input;
} else if (_parameter == PARAMETER.DEBT) {
terms.maxDebt = _input;
}
}
function deposit(uint256 _amount, uint256 _maxPrice) external returns (uint256) {
require(WETH.balanceOf(msg.sender) >= _amount, "Balance too low");
decayDebt();
uint256 nativePrice = bondPrice();
require(_maxPrice >= nativePrice, "Slippage limit: more than max price");
uint256 value;
uint256 payout;
(payout, value) = payoutFor(_amount);
require(payout >= 10 ** ATLAS.decimals() / 100, "Bond too small");
require(payout <= maxPayout(), "Bond too large");
totalDebt = totalDebt.add(value);
require(totalDebt <= terms.maxDebt, "Max capacity reached");
bondInfo[msg.sender] = Bond({
payout: bondInfo[msg.sender].payout.add(payout),
vesting: terms.vestingTerm,
lastBlockTimestamp: block.timestamp,
truePricePaid: bondPrice()
});
totalPrincipalBonded = totalPrincipalBonded.add(_amount);
totalPayoutGiven = totalPayoutGiven.add(payout);
treasury.transferToBond(payout);
WETH.transferFrom(msg.sender, address(this), _amount);
swapETHForTokens(_amount);
emit BondCreated(_amount, payout, block.timestamp.add(terms.vestingTerm));
emit BondPriceChanged(_bondPrice(), debtRatio());
return payout;
}
function redeem() external returns (uint256) {
Bond memory info = bondInfo[msg.sender];
uint256 percentVested = percentVestedFor(msg.sender);
if (percentVested >= 10000) {
delete bondInfo[msg.sender];
emit BondRedeemed(msg.sender, info.payout, 0);
wsATLAS.transfer(msg.sender, info.payout);
return info.payout;
} else {
uint256 payout = info.payout.mul(percentVested).div(10000);
bondInfo[msg.sender] = Bond({
payout: info.payout.sub(payout),
vesting: info.vesting.sub(block.timestamp.sub(info.lastBlockTimestamp)),
lastBlockTimestamp: block.timestamp,
truePricePaid: info.truePricePaid
});
emit BondRedeemed(msg.sender, payout, bondInfo[msg.sender].payout);
wsATLAS.transfer(msg.sender, payout);
return payout;
}
}
function swapETHForTokens(uint256 ethAmount) internal {
address[] memory path = new address[](2);
path[0] = uniswapV2Router.WETH();
path[1] = address(ATLAS);
uniswapV2Router.swapExactTokensForTokensSupportingFeeOnTransferTokens(
ethAmount,
0,
path,
address(treasury),
block.timestamp
);
}
function decayDebt() internal {
totalDebt = totalDebt.sub(debtDecay());
lastDecay = block.timestamp;
}
function _bondPrice() internal returns (uint256 price_) {
price_ = terms.controlVariable.mul(debtRatio()).div(1e2);
if (price_ < terms.minimumPrice) {
price_ = terms.minimumPrice;
} else if (terms.minimumPrice != 0) {
terms.minimumPrice = 0;
}
}
function bondPrice() public view returns (uint256 price_) {
price_ = terms.controlVariable.mul(debtRatio()).div(1e2);
if (price_ < terms.minimumPrice) {
price_ = terms.minimumPrice;
}
}
function maxPayout() public view returns (uint256) {
return terms.maxPayout;
}
function payoutFor(uint256 _amount) public view returns (uint256 _payout, uint256 _value) {
_value = treasury.valueOfToken(address(WETH), _amount);
_payout = FixedPoint.fraction(_value, bondPrice()).decode112with18();
}
function debtRatio() public view returns (uint256 debtRatio_) {
debtRatio_ = FixedPoint.fraction(currentDebt().mul(10 ** ATLAS.decimals()), ATLAS.totalSupply()).decode112with18(
).div(1e9);
}
function currentDebt() public view returns (uint256) {
return totalDebt.sub(debtDecay());
}
function debtDecay() public view returns (uint256 decay_) {
uint256 timestampSinceLast = block.timestamp.sub(lastDecay);
decay_ = totalDebt.mul(timestampSinceLast).div(terms.vestingTerm);
if (decay_ > totalDebt) {
decay_ = totalDebt;
}
}
function percentVestedFor(address _depositor) public view returns (uint256 percentVested_) {
Bond memory bond = bondInfo[_depositor];
uint256 timestampSinceLast = block.timestamp.sub(bond.lastBlockTimestamp);
uint256 vesting = bond.vesting;
if (vesting > 0) {
percentVested_ = timestampSinceLast.mul(10000).div(vesting);
} else {
percentVested_ = 0;
}
}
function pendingPayoutFor(address _depositor) external view returns (uint256 pendingPayout_) {
uint256 percentVested = percentVestedFor(_depositor);
uint256 payout = bondInfo[_depositor].payout;
if (percentVested >= 10000) {
pendingPayout_ = payout;
} else {
pendingPayout_ = payout.mul(percentVested).div(10000);
}
}
}
文件 3 的 6:FixedPoint.sol
pragma solidity ^0.7.5;
import "./FullMath.sol";
library Babylonian {
function sqrt(uint256 x) internal pure returns (uint256) {
if (x == 0) return 0;
uint256 xx = x;
uint256 r = 1;
if (xx >= 0x100000000000000000000000000000000) {
xx >>= 128;
r <<= 64;
}
if (xx >= 0x10000000000000000) {
xx >>= 64;
r <<= 32;
}
if (xx >= 0x100000000) {
xx >>= 32;
r <<= 16;
}
if (xx >= 0x10000) {
xx >>= 16;
r <<= 8;
}
if (xx >= 0x100) {
xx >>= 8;
r <<= 4;
}
if (xx >= 0x10) {
xx >>= 4;
r <<= 2;
}
if (xx >= 0x8) {
r <<= 1;
}
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
r = (r + x / r) >> 1;
uint256 r1 = x / r;
return (r < r1 ? r : r1);
}
}
library BitMath {
function mostSignificantBit(uint256 x) internal pure returns (uint8 r) {
require(x > 0, 'BitMath::mostSignificantBit: zero');
if (x >= 0x100000000000000000000000000000000) {
x >>= 128;
r += 128;
}
if (x >= 0x10000000000000000) {
x >>= 64;
r += 64;
}
if (x >= 0x100000000) {
x >>= 32;
r += 32;
}
if (x >= 0x10000) {
x >>= 16;
r += 16;
}
if (x >= 0x100) {
x >>= 8;
r += 8;
}
if (x >= 0x10) {
x >>= 4;
r += 4;
}
if (x >= 0x4) {
x >>= 2;
r += 2;
}
if (x >= 0x2) r += 1;
}
}
library FixedPoint {
struct uq112x112 {
uint224 _x;
}
struct uq144x112 {
uint256 _x;
}
uint8 private constant RESOLUTION = 112;
uint256 private constant Q112 = 0x10000000000000000000000000000;
uint256 private constant Q224 = 0x100000000000000000000000000000000000000000000000000000000;
uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff;
function decode(uq112x112 memory self) internal pure returns (uint112) {
return uint112(self._x >> RESOLUTION);
}
function decode112with18(uq112x112 memory self) internal pure returns (uint) {
return uint(self._x) / 5192296858534827;
}
function fraction(uint256 numerator, uint256 denominator) internal pure returns (uq112x112 memory) {
require(denominator > 0, 'FixedPoint::fraction: division by zero');
if (numerator == 0) return FixedPoint.uq112x112(0);
if (numerator <= uint144(-1)) {
uint256 result = (numerator << RESOLUTION) / denominator;
require(result <= uint224(-1), 'FixedPoint::fraction: overflow');
return uq112x112(uint224(result));
} else {
uint256 result = FullMath.mulDiv(numerator, Q112, denominator);
require(result <= uint224(-1), 'FixedPoint::fraction: overflow');
return uq112x112(uint224(result));
}
}
function sqrt(uq112x112 memory self) internal pure returns (uq112x112 memory) {
if (self._x <= uint144(-1)) {
return uq112x112(uint224(Babylonian.sqrt(uint256(self._x) << 112)));
}
uint8 safeShiftBits = 255 - BitMath.mostSignificantBit(self._x);
safeShiftBits -= safeShiftBits % 2;
return uq112x112(uint224(Babylonian.sqrt(uint256(self._x) << safeShiftBits) << ((112 - safeShiftBits) / 2)));
}
}
文件 4 的 6:FullMath.sol
pragma solidity ^0.7.5;
library FullMath {
function fullMul(uint256 x, uint256 y) private pure returns (uint256 l, uint256 h) {
uint256 mm = mulmod(x, y, uint256(-1));
l = x * y;
h = mm - l;
if (mm < l) h -= 1;
}
function fullDiv(
uint256 l,
uint256 h,
uint256 d
) private pure returns (uint256) {
uint256 pow2 = d & -d;
d /= pow2;
l /= pow2;
l += h * ((-pow2) / pow2 + 1);
uint256 r = 1;
r *= 2 - d * r;
r *= 2 - d * r;
r *= 2 - d * r;
r *= 2 - d * r;
r *= 2 - d * r;
r *= 2 - d * r;
r *= 2 - d * r;
r *= 2 - d * r;
return l * r;
}
function mulDiv(
uint256 x,
uint256 y,
uint256 d
) internal pure returns (uint256) {
(uint256 l, uint256 h) = fullMul(x, y);
uint256 mm = mulmod(x, y, d);
if (mm > l) h -= 1;
l -= mm;
if (h == 0) return l / d;
require(h < d, 'FullMath: FULLDIV_OVERFLOW');
return fullDiv(l, h, d);
}
}
文件 5 的 6:IERC20.sol
pragma solidity >=0.7.5;
interface IERC20 {
function decimals() external view returns (uint8);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 6 的 6:SafeMath.sol
pragma solidity ^0.7.5;
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
assert(a == b * c + a % b);
return c;
}
function sqrrt(uint256 a) internal pure returns (uint c) {
if (a > 3) {
c = a;
uint b = add( div( a, 2), 1 );
while (b < c) {
c = b;
b = div( add( div( a, b ), b), 2 );
}
} else if (a != 0) {
c = 1;
}
}
}
{
"compilationTarget": {
"contracts/Atlas/Bond.sol": "AtlasBonding"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 1000
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_treasury","type":"address"},{"internalType":"address","name":"_wsATLAS","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"deposit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"payout","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"expires","type":"uint256"}],"name":"BondCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"internalPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"debtRatio","type":"uint256"}],"name":"BondPriceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"payout","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"remaining","type":"uint256"}],"name":"BondRedeemed","type":"event"},{"inputs":[],"name":"ATLAS","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"bondInfo","outputs":[{"internalType":"uint256","name":"payout","type":"uint256"},{"internalType":"uint256","name":"vesting","type":"uint256"},{"internalType":"uint256","name":"lastBlockTimestamp","type":"uint256"},{"internalType":"uint256","name":"truePricePaid","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bondPrice","outputs":[{"internalType":"uint256","name":"price_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"debtDecay","outputs":[{"internalType":"uint256","name":"decay_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"debtRatio","outputs":[{"internalType":"uint256","name":"debtRatio_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_maxPrice","type":"uint256"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_controlVariable","type":"uint256"},{"internalType":"uint256","name":"_vestingTerm","type":"uint256"},{"internalType":"uint256","name":"_minimumPrice","type":"uint256"},{"internalType":"uint256","name":"_maxPayout","type":"uint256"},{"internalType":"uint256","name":"_maxDebt","type":"uint256"},{"internalType":"uint256","name":"_initialDebt","type":"uint256"}],"name":"initializeBond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastDecay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPayout","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"payoutFor","outputs":[{"internalType":"uint256","name":"_payout","type":"uint256"},{"internalType":"uint256","name":"_value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_depositor","type":"address"}],"name":"pendingPayoutFor","outputs":[{"internalType":"uint256","name":"pendingPayout_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_depositor","type":"address"}],"name":"percentVestedFor","outputs":[{"internalType":"uint256","name":"percentVested_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"redeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum AtlasBonding.PARAMETER","name":"_parameter","type":"uint8"},{"internalType":"uint256","name":"_input","type":"uint256"}],"name":"setBondTerms","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"terms","outputs":[{"internalType":"uint256","name":"controlVariable","type":"uint256"},{"internalType":"uint256","name":"vestingTerm","type":"uint256"},{"internalType":"uint256","name":"minimumPrice","type":"uint256"},{"internalType":"uint256","name":"maxPayout","type":"uint256"},{"internalType":"uint256","name":"maxDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalPayoutGiven","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalPrincipalBonded","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"contract ITreasury","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapV2Router","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wsATLAS","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"}]