编译器
0.8.21+commit.d9974bed
文件 1 的 22:AggregatorV3Interface.sol
pragma solidity ^0.8.0;
interface AggregatorV3Interface {
function decimals() external view returns (uint8);
function description() external view returns (string memory);
function version() external view returns (uint256);
function getRoundData(
uint80 _roundId
) external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
function latestRoundData()
external
view
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
}
文件 2 的 22:Casting.sol
pragma solidity >=0.8.19;
import "./Errors.sol" as CastingErrors;
import { MAX_UINT128, MAX_UINT40 } from "../Common.sol";
import { uMAX_SD1x18 } from "../sd1x18/Constants.sol";
import { SD1x18 } from "../sd1x18/ValueType.sol";
import { uMAX_SD59x18 } from "../sd59x18/Constants.sol";
import { SD59x18 } from "../sd59x18/ValueType.sol";
import { uMAX_UD2x18 } from "../ud2x18/Constants.sol";
import { UD2x18 } from "../ud2x18/ValueType.sol";
import { UD60x18 } from "./ValueType.sol";
function intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {
uint256 xUint = UD60x18.unwrap(x);
if (xUint > uint256(int256(uMAX_SD1x18))) {
revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);
}
result = SD1x18.wrap(int64(uint64(xUint)));
}
function intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {
uint256 xUint = UD60x18.unwrap(x);
if (xUint > uMAX_UD2x18) {
revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);
}
result = UD2x18.wrap(uint64(xUint));
}
function intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {
uint256 xUint = UD60x18.unwrap(x);
if (xUint > uint256(uMAX_SD59x18)) {
revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);
}
result = SD59x18.wrap(int256(xUint));
}
function intoUint256(UD60x18 x) pure returns (uint256 result) {
result = UD60x18.unwrap(x);
}
function intoUint128(UD60x18 x) pure returns (uint128 result) {
uint256 xUint = UD60x18.unwrap(x);
if (xUint > MAX_UINT128) {
revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);
}
result = uint128(xUint);
}
function intoUint40(UD60x18 x) pure returns (uint40 result) {
uint256 xUint = UD60x18.unwrap(x);
if (xUint > MAX_UINT40) {
revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);
}
result = uint40(xUint);
}
function ud(uint256 x) pure returns (UD60x18 result) {
result = UD60x18.wrap(x);
}
function ud60x18(uint256 x) pure returns (UD60x18 result) {
result = UD60x18.wrap(x);
}
function unwrap(UD60x18 x) pure returns (uint256 result) {
result = UD60x18.unwrap(x);
}
function wrap(uint256 x) pure returns (UD60x18 result) {
result = UD60x18.wrap(x);
}
文件 3 的 22:Common.sol
pragma solidity >=0.8.19;
error PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);
error PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);
error PRBMath_MulDivSigned_InputTooSmall();
error PRBMath_MulDivSigned_Overflow(int256 x, int256 y);
uint128 constant MAX_UINT128 = type(uint128).max;
uint40 constant MAX_UINT40 = type(uint40).max;
uint256 constant UNIT = 1e18;
uint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;
uint256 constant UNIT_LPOTD = 262144;
function exp2(uint256 x) pure returns (uint256 result) {
unchecked {
result = 0x800000000000000000000000000000000000000000000000;
if (x & 0xFF00000000000000 > 0) {
if (x & 0x8000000000000000 > 0) {
result = (result * 0x16A09E667F3BCC909) >> 64;
}
if (x & 0x4000000000000000 > 0) {
result = (result * 0x1306FE0A31B7152DF) >> 64;
}
if (x & 0x2000000000000000 > 0) {
result = (result * 0x1172B83C7D517ADCE) >> 64;
}
if (x & 0x1000000000000000 > 0) {
result = (result * 0x10B5586CF9890F62A) >> 64;
}
if (x & 0x800000000000000 > 0) {
result = (result * 0x1059B0D31585743AE) >> 64;
}
if (x & 0x400000000000000 > 0) {
result = (result * 0x102C9A3E778060EE7) >> 64;
}
if (x & 0x200000000000000 > 0) {
result = (result * 0x10163DA9FB33356D8) >> 64;
}
if (x & 0x100000000000000 > 0) {
result = (result * 0x100B1AFA5ABCBED61) >> 64;
}
}
if (x & 0xFF000000000000 > 0) {
if (x & 0x80000000000000 > 0) {
result = (result * 0x10058C86DA1C09EA2) >> 64;
}
if (x & 0x40000000000000 > 0) {
result = (result * 0x1002C605E2E8CEC50) >> 64;
}
if (x & 0x20000000000000 > 0) {
result = (result * 0x100162F3904051FA1) >> 64;
}
if (x & 0x10000000000000 > 0) {
result = (result * 0x1000B175EFFDC76BA) >> 64;
}
if (x & 0x8000000000000 > 0) {
result = (result * 0x100058BA01FB9F96D) >> 64;
}
if (x & 0x4000000000000 > 0) {
result = (result * 0x10002C5CC37DA9492) >> 64;
}
if (x & 0x2000000000000 > 0) {
result = (result * 0x1000162E525EE0547) >> 64;
}
if (x & 0x1000000000000 > 0) {
result = (result * 0x10000B17255775C04) >> 64;
}
}
if (x & 0xFF0000000000 > 0) {
if (x & 0x800000000000 > 0) {
result = (result * 0x1000058B91B5BC9AE) >> 64;
}
if (x & 0x400000000000 > 0) {
result = (result * 0x100002C5C89D5EC6D) >> 64;
}
if (x & 0x200000000000 > 0) {
result = (result * 0x10000162E43F4F831) >> 64;
}
if (x & 0x100000000000 > 0) {
result = (result * 0x100000B1721BCFC9A) >> 64;
}
if (x & 0x80000000000 > 0) {
result = (result * 0x10000058B90CF1E6E) >> 64;
}
if (x & 0x40000000000 > 0) {
result = (result * 0x1000002C5C863B73F) >> 64;
}
if (x & 0x20000000000 > 0) {
result = (result * 0x100000162E430E5A2) >> 64;
}
if (x & 0x10000000000 > 0) {
result = (result * 0x1000000B172183551) >> 64;
}
}
if (x & 0xFF00000000 > 0) {
if (x & 0x8000000000 > 0) {
result = (result * 0x100000058B90C0B49) >> 64;
}
if (x & 0x4000000000 > 0) {
result = (result * 0x10000002C5C8601CC) >> 64;
}
if (x & 0x2000000000 > 0) {
result = (result * 0x1000000162E42FFF0) >> 64;
}
if (x & 0x1000000000 > 0) {
result = (result * 0x10000000B17217FBB) >> 64;
}
if (x & 0x800000000 > 0) {
result = (result * 0x1000000058B90BFCE) >> 64;
}
if (x & 0x400000000 > 0) {
result = (result * 0x100000002C5C85FE3) >> 64;
}
if (x & 0x200000000 > 0) {
result = (result * 0x10000000162E42FF1) >> 64;
}
if (x & 0x100000000 > 0) {
result = (result * 0x100000000B17217F8) >> 64;
}
}
if (x & 0xFF000000 > 0) {
if (x & 0x80000000 > 0) {
result = (result * 0x10000000058B90BFC) >> 64;
}
if (x & 0x40000000 > 0) {
result = (result * 0x1000000002C5C85FE) >> 64;
}
if (x & 0x20000000 > 0) {
result = (result * 0x100000000162E42FF) >> 64;
}
if (x & 0x10000000 > 0) {
result = (result * 0x1000000000B17217F) >> 64;
}
if (x & 0x8000000 > 0) {
result = (result * 0x100000000058B90C0) >> 64;
}
if (x & 0x4000000 > 0) {
result = (result * 0x10000000002C5C860) >> 64;
}
if (x & 0x2000000 > 0) {
result = (result * 0x1000000000162E430) >> 64;
}
if (x & 0x1000000 > 0) {
result = (result * 0x10000000000B17218) >> 64;
}
}
if (x & 0xFF0000 > 0) {
if (x & 0x800000 > 0) {
result = (result * 0x1000000000058B90C) >> 64;
}
if (x & 0x400000 > 0) {
result = (result * 0x100000000002C5C86) >> 64;
}
if (x & 0x200000 > 0) {
result = (result * 0x10000000000162E43) >> 64;
}
if (x & 0x100000 > 0) {
result = (result * 0x100000000000B1721) >> 64;
}
if (x & 0x80000 > 0) {
result = (result * 0x10000000000058B91) >> 64;
}
if (x & 0x40000 > 0) {
result = (result * 0x1000000000002C5C8) >> 64;
}
if (x & 0x20000 > 0) {
result = (result * 0x100000000000162E4) >> 64;
}
if (x & 0x10000 > 0) {
result = (result * 0x1000000000000B172) >> 64;
}
}
if (x & 0xFF00 > 0) {
if (x & 0x8000 > 0) {
result = (result * 0x100000000000058B9) >> 64;
}
if (x & 0x4000 > 0) {
result = (result * 0x10000000000002C5D) >> 64;
}
if (x & 0x2000 > 0) {
result = (result * 0x1000000000000162E) >> 64;
}
if (x & 0x1000 > 0) {
result = (result * 0x10000000000000B17) >> 64;
}
if (x & 0x800 > 0) {
result = (result * 0x1000000000000058C) >> 64;
}
if (x & 0x400 > 0) {
result = (result * 0x100000000000002C6) >> 64;
}
if (x & 0x200 > 0) {
result = (result * 0x10000000000000163) >> 64;
}
if (x & 0x100 > 0) {
result = (result * 0x100000000000000B1) >> 64;
}
}
if (x & 0xFF > 0) {
if (x & 0x80 > 0) {
result = (result * 0x10000000000000059) >> 64;
}
if (x & 0x40 > 0) {
result = (result * 0x1000000000000002C) >> 64;
}
if (x & 0x20 > 0) {
result = (result * 0x10000000000000016) >> 64;
}
if (x & 0x10 > 0) {
result = (result * 0x1000000000000000B) >> 64;
}
if (x & 0x8 > 0) {
result = (result * 0x10000000000000006) >> 64;
}
if (x & 0x4 > 0) {
result = (result * 0x10000000000000003) >> 64;
}
if (x & 0x2 > 0) {
result = (result * 0x10000000000000001) >> 64;
}
if (x & 0x1 > 0) {
result = (result * 0x10000000000000001) >> 64;
}
}
result *= UNIT;
result >>= (191 - (x >> 64));
}
}
function msb(uint256 x) pure returns (uint256 result) {
assembly ("memory-safe") {
let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))
x := shr(factor, x)
result := or(result, factor)
}
assembly ("memory-safe") {
let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))
x := shr(factor, x)
result := or(result, factor)
}
assembly ("memory-safe") {
let factor := shl(5, gt(x, 0xFFFFFFFF))
x := shr(factor, x)
result := or(result, factor)
}
assembly ("memory-safe") {
let factor := shl(4, gt(x, 0xFFFF))
x := shr(factor, x)
result := or(result, factor)
}
assembly ("memory-safe") {
let factor := shl(3, gt(x, 0xFF))
x := shr(factor, x)
result := or(result, factor)
}
assembly ("memory-safe") {
let factor := shl(2, gt(x, 0xF))
x := shr(factor, x)
result := or(result, factor)
}
assembly ("memory-safe") {
let factor := shl(1, gt(x, 0x3))
x := shr(factor, x)
result := or(result, factor)
}
assembly ("memory-safe") {
let factor := gt(x, 0x1)
result := or(result, factor)
}
}
function mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {
uint256 prod0;
uint256 prod1;
assembly ("memory-safe") {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
unchecked {
return prod0 / denominator;
}
}
if (prod1 >= denominator) {
revert PRBMath_MulDiv_Overflow(x, y, denominator);
}
uint256 remainder;
assembly ("memory-safe") {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
unchecked {
uint256 lpotdod = denominator & (~denominator + 1);
uint256 flippedLpotdod;
assembly ("memory-safe") {
denominator := div(denominator, lpotdod)
prod0 := div(prod0, lpotdod)
flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)
}
prod0 |= prod1 * flippedLpotdod;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
}
}
function mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {
uint256 prod0;
uint256 prod1;
assembly ("memory-safe") {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
unchecked {
return prod0 / UNIT;
}
}
if (prod1 >= UNIT) {
revert PRBMath_MulDiv18_Overflow(x, y);
}
uint256 remainder;
assembly ("memory-safe") {
remainder := mulmod(x, y, UNIT)
result :=
mul(
or(
div(sub(prod0, remainder), UNIT_LPOTD),
mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))
),
UNIT_INVERSE
)
}
}
function mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {
if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {
revert PRBMath_MulDivSigned_InputTooSmall();
}
uint256 xAbs;
uint256 yAbs;
uint256 dAbs;
unchecked {
xAbs = x < 0 ? uint256(-x) : uint256(x);
yAbs = y < 0 ? uint256(-y) : uint256(y);
dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);
}
uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);
if (resultAbs > uint256(type(int256).max)) {
revert PRBMath_MulDivSigned_Overflow(x, y);
}
uint256 sx;
uint256 sy;
uint256 sd;
assembly ("memory-safe") {
sx := sgt(x, sub(0, 1))
sy := sgt(y, sub(0, 1))
sd := sgt(denominator, sub(0, 1))
}
unchecked {
result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);
}
}
function sqrt(uint256 x) pure returns (uint256 result) {
if (x == 0) {
return 0;
}
uint256 xAux = uint256(x);
result = 1;
if (xAux >= 2 ** 128) {
xAux >>= 128;
result <<= 64;
}
if (xAux >= 2 ** 64) {
xAux >>= 64;
result <<= 32;
}
if (xAux >= 2 ** 32) {
xAux >>= 32;
result <<= 16;
}
if (xAux >= 2 ** 16) {
xAux >>= 16;
result <<= 8;
}
if (xAux >= 2 ** 8) {
xAux >>= 8;
result <<= 4;
}
if (xAux >= 2 ** 4) {
xAux >>= 4;
result <<= 2;
}
if (xAux >= 2 ** 2) {
result <<= 1;
}
unchecked {
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
uint256 roundedResult = x / result;
if (result >= roundedResult) {
result = roundedResult;
}
}
}
文件 4 的 22:Constants.sol
pragma solidity >=0.8.19;
import { SD1x18 } from "./ValueType.sol";
SD1x18 constant E = SD1x18.wrap(2_718281828459045235);
int64 constant uMAX_SD1x18 = 9_223372036854775807;
SD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);
int64 constant uMIN_SD1x18 = -9_223372036854775808;
SD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);
SD1x18 constant PI = SD1x18.wrap(3_141592653589793238);
SD1x18 constant UNIT = SD1x18.wrap(1e18);
int256 constant uUNIT = 1e18;
文件 5 的 22:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 6 的 22:Conversions.sol
pragma solidity >=0.8.19;
import { uMAX_SD59x18, uMIN_SD59x18, uUNIT } from "./Constants.sol";
import { PRBMath_SD59x18_Convert_Overflow, PRBMath_SD59x18_Convert_Underflow } from "./Errors.sol";
import { SD59x18 } from "./ValueType.sol";
function convert(int256 x) pure returns (SD59x18 result) {
if (x < uMIN_SD59x18 / uUNIT) {
revert PRBMath_SD59x18_Convert_Underflow(x);
}
if (x > uMAX_SD59x18 / uUNIT) {
revert PRBMath_SD59x18_Convert_Overflow(x);
}
unchecked {
result = SD59x18.wrap(x * uUNIT);
}
}
function convert(SD59x18 x) pure returns (int256 result) {
result = SD59x18.unwrap(x) / uUNIT;
}
文件 7 的 22:ERC20.sol
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";
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;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function decimals() public view virtual override returns (uint8) {
return 18;
}
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
function _transfer(address from, address to, uint256 amount) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
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;
unchecked {
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
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);
}
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);
}
function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}
function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}
}
文件 8 的 22:Errors.sol
pragma solidity >=0.8.19;
import { UD2x18 } from "./ValueType.sol";
error PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);
error PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);
文件 9 的 22:Helpers.sol
pragma solidity >=0.8.19;
import { wrap } from "./Casting.sol";
import { SD59x18 } from "./ValueType.sol";
function add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {
return wrap(x.unwrap() + y.unwrap());
}
function and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {
return wrap(x.unwrap() & bits);
}
function and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {
return wrap(x.unwrap() & y.unwrap());
}
function eq(SD59x18 x, SD59x18 y) pure returns (bool result) {
result = x.unwrap() == y.unwrap();
}
function gt(SD59x18 x, SD59x18 y) pure returns (bool result) {
result = x.unwrap() > y.unwrap();
}
function gte(SD59x18 x, SD59x18 y) pure returns (bool result) {
result = x.unwrap() >= y.unwrap();
}
function isZero(SD59x18 x) pure returns (bool result) {
result = x.unwrap() == 0;
}
function lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {
result = wrap(x.unwrap() << bits);
}
function lt(SD59x18 x, SD59x18 y) pure returns (bool result) {
result = x.unwrap() < y.unwrap();
}
function lte(SD59x18 x, SD59x18 y) pure returns (bool result) {
result = x.unwrap() <= y.unwrap();
}
function mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {
result = wrap(x.unwrap() % y.unwrap());
}
function neq(SD59x18 x, SD59x18 y) pure returns (bool result) {
result = x.unwrap() != y.unwrap();
}
function not(SD59x18 x) pure returns (SD59x18 result) {
result = wrap(~x.unwrap());
}
function or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {
result = wrap(x.unwrap() | y.unwrap());
}
function rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {
result = wrap(x.unwrap() >> bits);
}
function sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {
result = wrap(x.unwrap() - y.unwrap());
}
function unary(SD59x18 x) pure returns (SD59x18 result) {
result = wrap(-x.unwrap());
}
function uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {
unchecked {
result = wrap(x.unwrap() + y.unwrap());
}
}
function uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {
unchecked {
result = wrap(x.unwrap() - y.unwrap());
}
}
function uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {
unchecked {
result = wrap(-x.unwrap());
}
}
function xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {
result = wrap(x.unwrap() ^ y.unwrap());
}
文件 10 的 22:IChainlinkPriceConsumer.sol
pragma solidity ^0.8.9;
interface IChainlinkPriceConsumer {
function getLatestData() external view returns (int);
function getHistoricalPrice(uint80 roundId) external view returns (int256);
}
文件 11 的 22:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, 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 from, address to, uint256 amount) external returns (bool);
}
文件 12 的 22:IERC20Metadata.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
interface IERC20Metadata is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
文件 13 的 22:Math.sol
pragma solidity >=0.8.19;
import "../Common.sol" as Common;
import "./Errors.sol" as Errors;
import { wrap } from "./Casting.sol";
import {
uEXP_MAX_INPUT,
uEXP2_MAX_INPUT,
uHALF_UNIT,
uLOG2_10,
uLOG2_E,
uMAX_UD60x18,
uMAX_WHOLE_UD60x18,
UNIT,
uUNIT,
uUNIT_SQUARED,
ZERO
} from "./Constants.sol";
import { UD60x18 } from "./ValueType.sol";
function avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {
uint256 xUint = x.unwrap();
uint256 yUint = y.unwrap();
unchecked {
result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));
}
}
function ceil(UD60x18 x) pure returns (UD60x18 result) {
uint256 xUint = x.unwrap();
if (xUint > uMAX_WHOLE_UD60x18) {
revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);
}
assembly ("memory-safe") {
let remainder := mod(x, uUNIT)
let delta := sub(uUNIT, remainder)
result := add(x, mul(delta, gt(remainder, 0)))
}
}
function div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {
result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));
}
function exp(UD60x18 x) pure returns (UD60x18 result) {
uint256 xUint = x.unwrap();
if (xUint > uEXP_MAX_INPUT) {
revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);
}
unchecked {
uint256 doubleUnitProduct = xUint * uLOG2_E;
result = exp2(wrap(doubleUnitProduct / uUNIT));
}
}
function exp2(UD60x18 x) pure returns (UD60x18 result) {
uint256 xUint = x.unwrap();
if (xUint > uEXP2_MAX_INPUT) {
revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);
}
uint256 x_192x64 = (xUint << 64) / uUNIT;
result = wrap(Common.exp2(x_192x64));
}
function floor(UD60x18 x) pure returns (UD60x18 result) {
assembly ("memory-safe") {
let remainder := mod(x, uUNIT)
result := sub(x, mul(remainder, gt(remainder, 0)))
}
}
function frac(UD60x18 x) pure returns (UD60x18 result) {
assembly ("memory-safe") {
result := mod(x, uUNIT)
}
}
function gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {
uint256 xUint = x.unwrap();
uint256 yUint = y.unwrap();
if (xUint == 0 || yUint == 0) {
return ZERO;
}
unchecked {
uint256 xyUint = xUint * yUint;
if (xyUint / xUint != yUint) {
revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);
}
result = wrap(Common.sqrt(xyUint));
}
}
function inv(UD60x18 x) pure returns (UD60x18 result) {
unchecked {
result = wrap(uUNIT_SQUARED / x.unwrap());
}
}
function ln(UD60x18 x) pure returns (UD60x18 result) {
unchecked {
result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);
}
}
function log10(UD60x18 x) pure returns (UD60x18 result) {
uint256 xUint = x.unwrap();
if (xUint < uUNIT) {
revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);
}
assembly ("memory-safe") {
switch x
case 1 { result := mul(uUNIT, sub(0, 18)) }
case 10 { result := mul(uUNIT, sub(1, 18)) }
case 100 { result := mul(uUNIT, sub(2, 18)) }
case 1000 { result := mul(uUNIT, sub(3, 18)) }
case 10000 { result := mul(uUNIT, sub(4, 18)) }
case 100000 { result := mul(uUNIT, sub(5, 18)) }
case 1000000 { result := mul(uUNIT, sub(6, 18)) }
case 10000000 { result := mul(uUNIT, sub(7, 18)) }
case 100000000 { result := mul(uUNIT, sub(8, 18)) }
case 1000000000 { result := mul(uUNIT, sub(9, 18)) }
case 10000000000 { result := mul(uUNIT, sub(10, 18)) }
case 100000000000 { result := mul(uUNIT, sub(11, 18)) }
case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }
case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }
case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }
case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }
case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }
case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }
case 1000000000000000000 { result := 0 }
case 10000000000000000000 { result := uUNIT }
case 100000000000000000000 { result := mul(uUNIT, 2) }
case 1000000000000000000000 { result := mul(uUNIT, 3) }
case 10000000000000000000000 { result := mul(uUNIT, 4) }
case 100000000000000000000000 { result := mul(uUNIT, 5) }
case 1000000000000000000000000 { result := mul(uUNIT, 6) }
case 10000000000000000000000000 { result := mul(uUNIT, 7) }
case 100000000000000000000000000 { result := mul(uUNIT, 8) }
case 1000000000000000000000000000 { result := mul(uUNIT, 9) }
case 10000000000000000000000000000 { result := mul(uUNIT, 10) }
case 100000000000000000000000000000 { result := mul(uUNIT, 11) }
case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }
case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }
case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }
case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }
case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }
case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }
case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }
case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }
case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }
case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }
case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }
case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }
case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }
case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }
case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }
case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }
case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }
case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }
case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }
case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }
case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }
case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }
case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }
case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }
case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }
case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }
case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }
case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }
case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }
case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }
case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }
case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }
case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }
case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }
case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }
case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }
case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }
case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }
case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }
case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }
case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }
case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }
case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }
case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }
case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }
case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }
case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }
case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }
default { result := uMAX_UD60x18 }
}
if (result.unwrap() == uMAX_UD60x18) {
unchecked {
result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);
}
}
}
function log2(UD60x18 x) pure returns (UD60x18 result) {
uint256 xUint = x.unwrap();
if (xUint < uUNIT) {
revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);
}
unchecked {
uint256 n = Common.msb(xUint / uUNIT);
uint256 resultUint = n * uUNIT;
uint256 y = xUint >> n;
if (y == uUNIT) {
return wrap(resultUint);
}
uint256 DOUBLE_UNIT = 2e18;
for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {
y = (y * y) / uUNIT;
if (y >= DOUBLE_UNIT) {
resultUint += delta;
y >>= 1;
}
}
result = wrap(resultUint);
}
}
function mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {
result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));
}
function pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {
uint256 xUint = x.unwrap();
uint256 yUint = y.unwrap();
if (xUint == 0) {
return yUint == 0 ? UNIT : ZERO;
}
else if (xUint == uUNIT) {
return UNIT;
}
if (yUint == 0) {
return UNIT;
}
else if (yUint == uUNIT) {
return x;
}
if (xUint > uUNIT) {
result = exp2(mul(log2(x), y));
}
else {
UD60x18 i = wrap(uUNIT_SQUARED / xUint);
UD60x18 w = exp2(mul(log2(i), y));
result = wrap(uUNIT_SQUARED / w.unwrap());
}
}
function powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {
uint256 xUint = x.unwrap();
uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;
for (y >>= 1; y > 0; y >>= 1) {
xUint = Common.mulDiv18(xUint, xUint);
if (y & 1 > 0) {
resultUint = Common.mulDiv18(resultUint, xUint);
}
}
result = wrap(resultUint);
}
function sqrt(UD60x18 x) pure returns (UD60x18 result) {
uint256 xUint = x.unwrap();
unchecked {
if (xUint > uMAX_UD60x18 / uUNIT) {
revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);
}
result = wrap(Common.sqrt(xUint * uUNIT));
}
}
文件 14 的 22:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 15 的 22:Ownable2Step.sol
pragma solidity ^0.8.0;
import "./Ownable.sol";
abstract contract Ownable2Step is Ownable {
address private _pendingOwner;
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
function pendingOwner() public view virtual returns (address) {
return _pendingOwner;
}
function transferOwnership(address newOwner) public virtual override onlyOwner {
_pendingOwner = newOwner;
emit OwnershipTransferStarted(owner(), newOwner);
}
function _transferOwnership(address newOwner) internal virtual override {
delete _pendingOwner;
super._transferOwnership(newOwner);
}
function acceptOwnership() public virtual {
address sender = _msgSender();
require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner");
_transferOwnership(sender);
}
}
文件 16 的 22:Pausable.sol
pragma solidity ^0.8.9;
import {UnrenounceableOwnable2Step} from "./UnrenounceableOwnable2Step.sol";
contract Pausable is UnrenounceableOwnable2Step {
address public pauser;
event Paused(address account);
event Unpaused(address account);
event PauserChanged(address indexed newAddress);
bool private _paused;
constructor() {
_paused = false;
pauser = msg.sender;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
modifier onlyPauser() {
require(msg.sender == pauser, "Pausable: caller is not the pauser");
_;
}
function pause() public onlyPauser returns (bool) {
_pause();
return (paused());
}
function unpause() public onlyPauser returns (bool) {
_unpause();
return (paused());
}
function updatePauser(address _newPauser) external onlyOwner {
require(
_newPauser != address(0),
"Pausable: new pauser is the zero address"
);
pauser = _newPauser;
emit PauserChanged(pauser);
}
}
文件 17 的 22:PurchasingCenter.sol
pragma solidity ^0.8.9;
import {ERC20} from "../lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";
import {IERC20} from "../lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import {Ownable} from "../lib/openzeppelin-contracts/contracts/access/Ownable.sol";
import {AggregatorV3Interface} from "../lib/chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import {IChainlinkPriceConsumer} from "./interfaces/IChainlinkPriceConsumer.sol";
import {Tiers} from "./Tiers.sol";
import {ReentrancyGuard} from "../lib/openzeppelin-contracts/contracts/security/ReentrancyGuard.sol";
import {SD59x18, sd, unwrap, ln, gt, frac} from "../lib/prb-math/src/SD59x18.sol";
import {UnrenounceableOwnable2Step} from "../lib/uranium-token/src/UnrenounceableOwnable2Step.sol";
import {Pausable} from "../lib/uranium-token/src/Pausable.sol";
contract PurchasingCenter is
UnrenounceableOwnable2Step,
Pausable,
Tiers,
ReentrancyGuard
{
IChainlinkPriceConsumer eth_pricer;
address public eth_usd_consumer_address;
mapping(Tier => TierDetails) public tier_to_tierDetails;
mapping(Tier => uint256) public tier_to_amountSold;
mapping(address => mapping(Tier => uint256))
public address_to_tier_to_contribution;
mapping(Tier => uint256) public tier_to_totalContribution;
mapping(address => mapping(Tier => uint256)) public address_to_tier_to_pwc;
mapping(Tier => uint256) public tier_to_tierPwc;
mapping(Tier => bool) public tier_oversubscribed;
mapping(address => mapping(Tier => bool))
public address_to_tier_to_boughtAlready;
address[] public tier1_buyers;
address[] public tier2_buyers;
address[] public tier3_buyers;
address[] public tier4_buyers;
uint256 public startTime;
uint256 public purchaseWindow;
uint256 public commodityPrice;
int256 public immutable sd59x18_decimals = 1e18;
bool public started;
event PurchaseStarted(uint256 startTime);
event NewPurchaseWindowSet(uint256 newPurchaseWindow);
event NewCommodityPriceSet(uint256 newPrice);
event NewEthUsdConsumerAddressSet(address newEthUsdConsumerAddress);
event NewTierDetailsSet(
uint256 newTier,
uint256 newSellAmount,
uint256 newDiscount,
uint256 newLockupTime,
uint256 newPurchaseCap
);
event TierContributionUpdated(uint256 tier, uint256 newContribution);
event PwcUpdated(uint256 tier, uint256 pwc);
event Oversubscribed(uint256 tier, address guyWhoPushedItOver);
event BoughtTokens(uint256 tier, address guy, uint256 eth_in);
event EthWithdrawn(address to, uint256 balance);
event Log(string func, uint gas);
constructor(
uint256 _purchaseWindow,
uint256 _commodityPrice,
address _eth_usd_consumer_address
) {
started = false;
purchaseWindow = _purchaseWindow;
commodityPrice = _commodityPrice;
eth_usd_consumer_address = _eth_usd_consumer_address;
eth_pricer = IChainlinkPriceConsumer(_eth_usd_consumer_address);
tier_to_tierDetails[Tier.tier1] = TierDetails(
87500 * 1e18,
0,
2 weeks,
100 ether
);
tier_to_tierDetails[Tier.tier2] = TierDetails(
75000 * 1e18,
10,
4 weeks,
100 ether
);
tier_to_tierDetails[Tier.tier3] = TierDetails(
50000 * 1e18,
20,
12 weeks,
75 ether
);
tier_to_tierDetails[Tier.tier4] = TierDetails(
37500 * 1e18,
30,
24 weeks,
50 ether
);
}
modifier everythingSet() {
require(purchaseWindow != 0, "purchaseWindow not set!");
require(commodityPrice != 0, "commodityPrice not set!");
require(
eth_usd_consumer_address != address(0),
"eth_usd_consumer_address not set!"
);
_;
}
modifier whenNotStarted() {
require(started == false, "Started already!");
_;
}
modifier whenStarted() {
require(started == true, "Not started yet!");
_;
}
function startPurchase() public onlyOwner whenNotStarted everythingSet {
startTime = block.timestamp;
started = true;
emit PurchaseStarted(startTime);
}
function setPurchaseWindow(
uint256 _purchaseWindow
) external onlyOwner whenNotStarted {
purchaseWindow = _purchaseWindow;
emit NewPurchaseWindowSet(purchaseWindow);
}
function setCommodityPrice(
uint256 price
) external onlyOwner whenNotStarted {
commodityPrice = price;
emit NewCommodityPriceSet(price);
}
function setEthUsdConsumerAddress(
address _eth_usd_consumer_address
) external onlyOwner whenPaused {
require(
_eth_usd_consumer_address != address(0),
"Address cannot be zero"
);
eth_usd_consumer_address = _eth_usd_consumer_address;
eth_pricer = IChainlinkPriceConsumer(_eth_usd_consumer_address);
emit NewEthUsdConsumerAddressSet(_eth_usd_consumer_address);
}
function setTierDetails(
uint256 tier,
uint256 sellAmount,
uint256 discount,
uint256 lockupTime,
uint256 purchaseCap
) external onlyOwner whenNotStarted {
Tier _tier = _t(tier);
require(sellAmount >= 0, "Invalid sellAmount");
require(discount >= 0 && discount <= 100, "Invalid discount");
require(lockupTime >= 0, "Invalid lockupTime");
require(purchaseCap >= 0, "Invalid purchaseCap");
tier_to_tierDetails[_tier] = TierDetails(
sellAmount,
discount,
lockupTime,
purchaseCap
);
emit NewTierDetailsSet(
tier,
sellAmount,
discount,
lockupTime,
purchaseCap
);
}
function ethPrice() public view returns (int256) {
int256 price = eth_pricer.getLatestData();
require(price != 0, "Stale price data");
return price;
}
function _discountedPrice(Tier tier) internal view returns (SD59x18) {
uint256 d;
if (tier == Tier.tier1) {
d = tier_to_tierDetails[Tier.tier1].discount;
} else if (tier == Tier.tier2) {
d = tier_to_tierDetails[Tier.tier2].discount;
} else if (tier == Tier.tier3) {
d = tier_to_tierDetails[Tier.tier3].discount;
} else if (tier == Tier.tier4) {
d = tier_to_tierDetails[Tier.tier4].discount;
}
SD59x18 _commodity_price = sd(
(int256(commodityPrice) * sd59x18_decimals)
);
SD59x18 _discounted = sd(int256(100 - d) * sd59x18_decimals);
SD59x18 _discounted_price = (_commodity_price.mul(_discounted)).div(
sd(int256(100) * sd59x18_decimals)
);
return _discounted_price;
}
function discountedPrice(uint256 tier) public view returns (uint256) {
Tier _tier = _t(tier);
SD59x18 _discounted_price = _discountedPrice(_tier);
uint256 price = uint256(unwrap(_discounted_price) / sd59x18_decimals);
return price;
}
function _ethInCommodityOut(
Tier tier,
uint256 eth_in
) internal view returns (SD59x18) {
SD59x18 _eth_price = sd(ethPrice() * sd59x18_decimals);
SD59x18 _price = _discountedPrice(tier);
SD59x18 _commodity_per_eth = _eth_price.div(_price);
SD59x18 _eth_in = sd(int256(eth_in) * sd59x18_decimals);
SD59x18 _commodityOut = _eth_in.mul(_commodity_per_eth);
return _commodityOut;
}
function ethInCommodityOut(
uint256 tier,
uint256 eth_in
) public view returns (uint256) {
Tier _tier = _t(tier);
SD59x18 _commodityOut = _ethInCommodityOut(_tier, eth_in);
uint256 commodityOut = uint256(
unwrap(_commodityOut) / sd59x18_decimals
);
return commodityOut;
}
function _price_weighted_contribution(
uint256 new_contribution,
uint256 eth_price
) internal pure returns (SD59x18) {
SD59x18 _new_contribution = sd(
int256(new_contribution) * sd59x18_decimals
);
SD59x18 _eth_price = sd(int256(eth_price) * sd59x18_decimals);
SD59x18 _pwc = _new_contribution.mul(_eth_price);
return _pwc;
}
function _pro_rata_amount(
address guy,
Tier tier
) internal view returns (SD59x18 _out) {
TierDetails memory details = tier_to_tierDetails[tier];
uint256 amountOnSale = details.amountOnSale;
SD59x18 _amountOnSale = sd(int256(amountOnSale) * sd59x18_decimals);
uint256 pwc = address_to_tier_to_pwc[guy][tier];
uint256 tier_pwc = tier_to_tierPwc[tier];
SD59x18 _pwc = sd(int256(pwc) * sd59x18_decimals);
SD59x18 _tier_pwc = sd(int256(tier_pwc) * sd59x18_decimals);
_out = _amountOnSale.mul(_pwc).div(_tier_pwc);
return _out;
}
function _amountToGet(
address guy,
Tier tier
) internal view returns (SD59x18 out) {
uint256 amountSold = tier_to_amountSold[tier];
if (amountSold == 0) {
return sd(int256(0));
}
uint256 tier_pwc = tier_to_tierPwc[tier];
if (tier_pwc == 0) {
return sd(int256(0));
}
SD59x18 _amountSold = sd(int256(amountSold) * sd59x18_decimals);
uint256 pwc = address_to_tier_to_pwc[guy][tier];
SD59x18 _pwc = sd(int256(pwc) * sd59x18_decimals);
SD59x18 _tier_pwc = sd(int256(tier_pwc) * sd59x18_decimals);
out = _amountSold.mul(_pwc).div(_tier_pwc);
return out;
}
function amountToGet(
address guy,
uint256 tier
) public view returns (uint256) {
Tier _tier = _t(tier);
SD59x18 _commodityYouGet = _amountToGet(guy, _tier);
uint256 commodityYouGet = uint256(
unwrap(_commodityYouGet) / sd59x18_decimals
);
return commodityYouGet;
}
function buyTokens(
uint256 tier
)
external
payable
whenStarted
whenNotPaused
nonReentrant
returns (bool success)
{
Tier _tier = _t(tier);
address guy = msg.sender;
uint256 eth_in = msg.value;
require(eth_in > 0, "Eth deposit cannot be 0");
uint256 purchaseCap = tier_to_tierDetails[_tier].purchaseCap;
uint256 eth_spent = address_to_tier_to_contribution[guy][_tier];
require(
eth_in + eth_spent <= purchaseCap,
"buyTokens(): over the purchaseCap!"
);
SD59x18 _commodityOut = _ethInCommodityOut(_tier, eth_in);
uint256 amountOut = uint256(unwrap(_commodityOut) / sd59x18_decimals);
uint256 amountSold = tier_to_amountSold[_tier];
uint256 amountOnSale = tier_to_tierDetails[_tier].amountOnSale;
require(
block.timestamp <= purchaseWindow + startTime,
"buyTokens(): sales over!"
);
if (amountSold + amountOut >= amountOnSale) {
tier_to_amountSold[_tier] = amountOnSale;
tier_oversubscribed[_tier] = true;
emit Oversubscribed(tier, guy);
} else {
tier_to_amountSold[_tier] += amountOut;
}
address_to_tier_to_contribution[guy][_tier] += eth_in;
tier_to_totalContribution[_tier] += eth_in;
emit TierContributionUpdated(tier, eth_in);
uint256 pwc = uint256(
unwrap(_price_weighted_contribution(eth_in, uint256(ethPrice()))) /
sd59x18_decimals
);
address_to_tier_to_pwc[guy][_tier] += pwc;
tier_to_tierPwc[_tier] += pwc;
emit PwcUpdated(tier, pwc);
bool didBuy = _bought(guy, tier);
emit BoughtTokens(tier, guy, eth_in);
return didBuy;
}
function _bought(address guy, uint256 tier) internal returns (bool didBuy) {
Tier _tier = _t(tier);
bool _bought_already = address_to_tier_to_boughtAlready[guy][_tier];
if (_bought_already) {
return true;
} else {
if (tier == 1) {
tier1_buyers.push(guy);
} else if (tier == 2) {
tier2_buyers.push(guy);
} else if (tier == 3) {
tier3_buyers.push(guy);
} else if (tier == 4) {
tier4_buyers.push(guy);
} else {
revert("Not valid tier");
}
address_to_tier_to_boughtAlready[guy][_tier] = true;
}
return true;
}
function _ethPayable(
address guy,
Tier tier
) internal view returns (SD59x18) {
SD59x18 _payableAmount;
if (tier_oversubscribed[tier]) {
uint256 contribution = address_to_tier_to_contribution[guy][tier];
if (contribution == 0) {
return sd(int256(0));
}
SD59x18 _commodityYouGet = _amountToGet(guy, tier);
SD59x18 _price = _discountedPrice(tier);
uint256 pwc = address_to_tier_to_pwc[guy][tier];
SD59x18 _pwc = sd(int256(pwc) * sd59x18_decimals);
SD59x18 _contribution = sd(int256(contribution) * sd59x18_decimals);
_payableAmount = _commodityYouGet.mul(_price).div(
_pwc.div(_contribution)
);
} else {
uint256 payableAmount = address_to_tier_to_contribution[guy][tier];
_payableAmount = sd(int256(payableAmount) * sd59x18_decimals);
}
return _payableAmount;
}
function ethPayable(
address guy,
uint256 tier
) public view returns (uint256) {
Tier _tier = _t(tier);
SD59x18 _payableAmount = _ethPayable(guy, _tier);
uint256 payableAmount = uint256(
unwrap(_payableAmount) / sd59x18_decimals
);
return payableAmount;
}
function refundAmount(
address guy,
uint256 tier
) public view returns (uint256) {
Tier _tier = _t(tier);
uint256 contribution = address_to_tier_to_contribution[guy][_tier];
uint256 payableAmount = ethPayable(guy, tier);
if (contribution == 0) {
return 0;
} else if (contribution <= payableAmount) {
return 0;
} else {
uint256 amount_to_refund = contribution - payableAmount;
return amount_to_refund;
}
}
function ethRefundable(uint256 tier) public view returns (uint256) {
uint256 totalRefund;
_t(tier);
uint256 _buyers = (tier == 1) ? tier1_buyers.length : (tier == 2)
? tier2_buyers.length
: (tier == 3)
? tier3_buyers.length
: (tier == 4)
? tier4_buyers.length
: 0;
require(_buyers != 0, "no buyers yet");
if (tier == 1) {
for (uint256 i = 0; i < _buyers; i++) {
address buyer = tier1_buyers[i];
uint256 refund = refundAmount(buyer, tier);
totalRefund += refund;
}
} else if (tier == 2) {
for (uint256 i = 0; i < _buyers; i++) {
address buyer = tier2_buyers[i];
uint256 refund = refundAmount(buyer, tier);
totalRefund += refund;
}
} else if (tier == 3) {
for (uint256 i = 0; i < _buyers; i++) {
address buyer = tier3_buyers[i];
uint256 refund = refundAmount(buyer, tier);
totalRefund += refund;
}
} else if (tier == 4) {
for (uint256 i = 0; i < _buyers; i++) {
address buyer = tier4_buyers[i];
uint256 refund = refundAmount(buyer, tier);
totalRefund += refund;
}
}
return totalRefund;
}
function ethRetainable(uint256 tier) external view returns (uint256) {
Tier _tier = _t(tier);
uint256 totalTierContribution = tier_to_totalContribution[_tier];
uint256 totalRefund = ethRefundable(tier);
uint256 retainable = totalTierContribution - totalRefund;
return retainable;
}
function salesOver() public view returns (bool) {
if (!started) {
return false;
} else if (block.timestamp <= purchaseWindow + startTime) {
return false;
} else {
return true;
}
}
function getContributionByUserAndTier(
address guy,
uint256 tier
) external view returns (uint256) {
Tier _tier = _t(tier);
uint256 contribution = address_to_tier_to_contribution[guy][_tier];
return contribution;
}
function getTokensBoughtByUserAndTier(
address guy,
uint256 tier
) external view returns (uint256) {
uint256 commodityYouGet = amountToGet(guy, tier);
return commodityYouGet;
}
function getOversubscribed(
uint256 tier
) external view returns (bool isOversubscribed) {
Tier _tier = _t(tier);
isOversubscribed = tier_oversubscribed[_tier];
return isOversubscribed;
}
function getAmountSoldByTier(uint256 tier) external view returns (uint256) {
Tier _tier = _t(tier);
return tier_to_amountSold[_tier];
}
function getRemainingAmountByTier(
uint256 tier
) external view returns (uint256) {
Tier _tier = _t(tier);
uint256 amountSold = tier_to_amountSold[_tier];
TierDetails memory details = tier_to_tierDetails[_tier];
uint256 amountOnSale = details.amountOnSale;
uint256 remaining = amountOnSale - amountSold;
return remaining;
}
function getTierDetails(
uint256 tier
)
external
view
returns (
uint256 amountOnSale,
uint256 discount,
uint256 lockupTime,
uint256 purchaseCap
)
{
Tier _tier = _t(tier);
TierDetails memory details = tier_to_tierDetails[_tier];
return (
details.amountOnSale,
details.discount,
details.lockupTime,
details.purchaseCap
);
}
function totalContribution(address guy) external view returns (uint256) {
uint256 tier1_contribution = address_to_tier_to_contribution[guy][
Tier.tier1
];
uint256 tier2_contribution = address_to_tier_to_contribution[guy][
Tier.tier2
];
uint256 tier3_contribution = address_to_tier_to_contribution[guy][
Tier.tier3
];
uint256 tier4_contribution = address_to_tier_to_contribution[guy][
Tier.tier4
];
uint256 aggregateContribution = tier1_contribution +
tier2_contribution +
tier3_contribution +
tier4_contribution;
return aggregateContribution;
}
function getPwcByUserAndTier(
address guy,
uint256 tier
) external view returns (uint256) {
Tier _tier = _t(tier);
uint256 pwc = address_to_tier_to_pwc[guy][_tier] / 10 ** 8;
return pwc;
}
function getTierPwc(uint256 tier) external view returns (uint256) {
Tier _tier = _t(tier);
uint256 tierPwc = tier_to_tierPwc[_tier] / 10 ** 8;
return tierPwc;
}
function totalAmountBought(address guy) external view returns (uint256) {
uint256 tier1_amount = amountToGet(guy, 1);
uint256 tier2_amount = amountToGet(guy, 2);
uint256 tier3_amount = amountToGet(guy, 3);
uint256 tier4_amount = amountToGet(guy, 4);
uint256 amount = tier1_amount +
tier2_amount +
tier3_amount +
tier4_amount;
return amount;
}
function tierContribution(uint tier) external view returns (uint256) {
Tier _tier = _t(tier);
uint256 amount = tier_to_totalContribution[_tier];
return amount;
}
function everythingIsSet() external view returns (bool) {
return (commodityPrice != 0 &&
purchaseWindow != 0 &&
eth_usd_consumer_address != address(0));
}
function getBoughtAlreadyByUserAndTier(
address guy,
uint256 tier
) external view returns (bool) {
Tier _tier = _t(tier);
bool boughtAlready = address_to_tier_to_boughtAlready[guy][_tier];
return boughtAlready;
}
function buyers(
uint256 tier
) external view returns (address[] memory buyersArray) {
if (tier == 1) {
return tier1_buyers;
} else if (tier == 2) {
return tier2_buyers;
} else if (tier == 3) {
return tier3_buyers;
} else if (tier == 4) {
return tier4_buyers;
} else {
revert("Not valid tier");
}
}
function withdrawEth(
address to
) external nonReentrant onlyOwner returns (bool) {
uint256 balance = address(this).balance;
(bool success, ) = payable(to).call{value: balance}("");
require(success, "Eth not withdrawn!");
emit EthWithdrawn(to, balance);
return success;
}
function ethBalance() public view returns (uint256 balance) {
balance = address(this).balance;
return balance;
}
fallback() external payable {
emit Log("receive", gasleft());
}
receive() external payable {
emit Log("receive", gasleft());
}
}
文件 18 的 22:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
}
function _nonReentrantAfter() private {
_status = _NOT_ENTERED;
}
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
}
文件 19 的 22:SD59x18.sol
pragma solidity >=0.8.19;
import "./sd59x18/Casting.sol";
import "./sd59x18/Constants.sol";
import "./sd59x18/Conversions.sol";
import "./sd59x18/Errors.sol";
import "./sd59x18/Helpers.sol";
import "./sd59x18/Math.sol";
import "./sd59x18/ValueType.sol";
文件 20 的 22:Tiers.sol
pragma solidity ^0.8.9;
contract Tiers {
enum Tier {
tier1,
tier2,
tier3,
tier4
}
struct TierDetails {
uint256 amountOnSale;
uint256 discount;
uint256 lockupTime;
uint256 purchaseCap;
}
function _t(uint256 tier) public pure returns (Tier) {
if (tier == 1) {
return Tier.tier1;
} else if (tier == 2) {
return Tier.tier2;
} else if (tier == 3) {
return Tier.tier3;
} else if (tier == 4) {
return Tier.tier4;
} else {
revert("Not valid tier");
}
}
}
文件 21 的 22:UnrenounceableOwnable2Step.sol
pragma solidity ^0.8.9;
import {Ownable2Step} from "../lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol";
contract UnrenounceableOwnable2Step is Ownable2Step {
function renounceOwnership() public view override onlyOwner {
revert("UnrenounceableOwnable2Step: renounceOwnership is disabled");
}
}
文件 22 的 22:ValueType.sol
pragma solidity >=0.8.19;
import "./Casting.sol" as Casting;
import "./Helpers.sol" as Helpers;
import "./Math.sol" as Math;
type SD59x18 is int256;
using {
Casting.intoInt256,
Casting.intoSD1x18,
Casting.intoUD2x18,
Casting.intoUD60x18,
Casting.intoUint256,
Casting.intoUint128,
Casting.intoUint40,
Casting.unwrap
} for SD59x18 global;
using {
Math.abs,
Math.avg,
Math.ceil,
Math.div,
Math.exp,
Math.exp2,
Math.floor,
Math.frac,
Math.gm,
Math.inv,
Math.log10,
Math.log2,
Math.ln,
Math.mul,
Math.pow,
Math.powu,
Math.sqrt
} for SD59x18 global;
using {
Helpers.add,
Helpers.and,
Helpers.eq,
Helpers.gt,
Helpers.gte,
Helpers.isZero,
Helpers.lshift,
Helpers.lt,
Helpers.lte,
Helpers.mod,
Helpers.neq,
Helpers.not,
Helpers.or,
Helpers.rshift,
Helpers.sub,
Helpers.uncheckedAdd,
Helpers.uncheckedSub,
Helpers.uncheckedUnary,
Helpers.xor
} for SD59x18 global;
using {
Helpers.add as +,
Helpers.and2 as &,
Math.div as /,
Helpers.eq as ==,
Helpers.gt as >,
Helpers.gte as >=,
Helpers.lt as <,
Helpers.lte as <=,
Helpers.mod as %,
Math.mul as *,
Helpers.neq as !=,
Helpers.not as ~,
Helpers.or as |,
Helpers.sub as -,
Helpers.unary as -,
Helpers.xor as ^
} for SD59x18 global;
{
"compilationTarget": {
"src/PurchasingCenter.sol": "PurchasingCenter"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":@prb-test/=lib/prb-test/src/",
":@prb/test/=lib/prb-math/lib/prb-test/src/",
":@uniswap/lib/=lib/uranium-token/lib/solidity-lib/",
":@uniswap/v2-core/=lib/uranium-token/lib/v2-core/",
":@uniswap/v2-periphery/=lib/pizza/lib/v2-periphery/contracts/",
":chainlink/=lib/chainlink/",
":ds-test/=lib/forge-std/lib/ds-test/src/",
":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
":forge-std/=lib/forge-std/src/",
":openzeppelin-contracts/=lib/openzeppelin-contracts/",
":openzeppelin/=lib/openzeppelin-contracts/contracts/",
":pizza-oracles/=lib/pizza-oracles/src/",
":pizza/=lib/pizza/",
":prb-math/=lib/prb-math/src/",
":prb-test/=lib/prb-test/src/",
":pyth-sdk-solidity/=lib/pizza/lib/pyth-sdk-solidity/",
":solidity-lib/=lib/pizza/lib/solidity-lib/contracts/",
":uranium-oracles/=lib/uranium-oracles/src/",
":uranium-token/=lib/uranium-token/",
":v2-core/=lib/pizza/lib/v2-core/contracts/",
":v2-periphery/=lib/pizza/lib/v2-periphery/contracts/"
]
}
[{"inputs":[{"internalType":"uint256","name":"_purchaseWindow","type":"uint256"},{"internalType":"uint256","name":"_commodityPrice","type":"uint256"},{"internalType":"address","name":"_eth_usd_consumer_address","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"PRBMath_MulDiv18_Overflow","type":"error"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"PRBMath_MulDiv_Overflow","type":"error"},{"inputs":[],"name":"PRBMath_SD59x18_Div_InputTooSmall","type":"error"},{"inputs":[{"internalType":"SD59x18","name":"x","type":"int256"},{"internalType":"SD59x18","name":"y","type":"int256"}],"name":"PRBMath_SD59x18_Div_Overflow","type":"error"},{"inputs":[],"name":"PRBMath_SD59x18_Mul_InputTooSmall","type":"error"},{"inputs":[{"internalType":"SD59x18","name":"x","type":"int256"},{"internalType":"SD59x18","name":"y","type":"int256"}],"name":"PRBMath_SD59x18_Mul_Overflow","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tier","type":"uint256"},{"indexed":false,"internalType":"address","name":"guy","type":"address"},{"indexed":false,"internalType":"uint256","name":"eth_in","type":"uint256"}],"name":"BoughtTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"}],"name":"EthWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"func","type":"string"},{"indexed":false,"internalType":"uint256","name":"gas","type":"uint256"}],"name":"Log","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"NewCommodityPriceSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newEthUsdConsumerAddress","type":"address"}],"name":"NewEthUsdConsumerAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newPurchaseWindow","type":"uint256"}],"name":"NewPurchaseWindowSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newTier","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newSellAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newDiscount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newLockupTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newPurchaseCap","type":"uint256"}],"name":"NewTierDetailsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tier","type":"uint256"},{"indexed":false,"internalType":"address","name":"guyWhoPushedItOver","type":"address"}],"name":"Oversubscribed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAddress","type":"address"}],"name":"PauserChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"startTime","type":"uint256"}],"name":"PurchaseStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tier","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"pwc","type":"uint256"}],"name":"PwcUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tier","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newContribution","type":"uint256"}],"name":"TierContributionUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"uint256","name":"tier","type":"uint256"}],"name":"_t","outputs":[{"internalType":"enum Tiers.Tier","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"enum Tiers.Tier","name":"","type":"uint8"}],"name":"address_to_tier_to_boughtAlready","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"enum Tiers.Tier","name":"","type":"uint8"}],"name":"address_to_tier_to_contribution","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"enum Tiers.Tier","name":"","type":"uint8"}],"name":"address_to_tier_to_pwc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"},{"internalType":"uint256","name":"tier","type":"uint256"}],"name":"amountToGet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tier","type":"uint256"}],"name":"buyTokens","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tier","type":"uint256"}],"name":"buyers","outputs":[{"internalType":"address[]","name":"buyersArray","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"commodityPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tier","type":"uint256"}],"name":"discountedPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ethBalance","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tier","type":"uint256"},{"internalType":"uint256","name":"eth_in","type":"uint256"}],"name":"ethInCommodityOut","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"},{"internalType":"uint256","name":"tier","type":"uint256"}],"name":"ethPayable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ethPrice","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tier","type":"uint256"}],"name":"ethRefundable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tier","type":"uint256"}],"name":"ethRetainable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eth_usd_consumer_address","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"everythingIsSet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tier","type":"uint256"}],"name":"getAmountSoldByTier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"},{"internalType":"uint256","name":"tier","type":"uint256"}],"name":"getBoughtAlreadyByUserAndTier","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"},{"internalType":"uint256","name":"tier","type":"uint256"}],"name":"getContributionByUserAndTier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tier","type":"uint256"}],"name":"getOversubscribed","outputs":[{"internalType":"bool","name":"isOversubscribed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"},{"internalType":"uint256","name":"tier","type":"uint256"}],"name":"getPwcByUserAndTier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tier","type":"uint256"}],"name":"getRemainingAmountByTier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tier","type":"uint256"}],"name":"getTierDetails","outputs":[{"internalType":"uint256","name":"amountOnSale","type":"uint256"},{"internalType":"uint256","name":"discount","type":"uint256"},{"internalType":"uint256","name":"lockupTime","type":"uint256"},{"internalType":"uint256","name":"purchaseCap","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tier","type":"uint256"}],"name":"getTierPwc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"},{"internalType":"uint256","name":"tier","type":"uint256"}],"name":"getTokensBoughtByUserAndTier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauser","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"purchaseWindow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"},{"internalType":"uint256","name":"tier","type":"uint256"}],"name":"refundAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"salesOver","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sd59x18_decimals","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"name":"setCommodityPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_eth_usd_consumer_address","type":"address"}],"name":"setEthUsdConsumerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_purchaseWindow","type":"uint256"}],"name":"setPurchaseWindow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tier","type":"uint256"},{"internalType":"uint256","name":"sellAmount","type":"uint256"},{"internalType":"uint256","name":"discount","type":"uint256"},{"internalType":"uint256","name":"lockupTime","type":"uint256"},{"internalType":"uint256","name":"purchaseCap","type":"uint256"}],"name":"setTierDetails","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startPurchase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"started","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tier1_buyers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tier2_buyers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tier3_buyers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tier4_buyers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tier","type":"uint256"}],"name":"tierContribution","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum Tiers.Tier","name":"","type":"uint8"}],"name":"tier_oversubscribed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum Tiers.Tier","name":"","type":"uint8"}],"name":"tier_to_amountSold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum Tiers.Tier","name":"","type":"uint8"}],"name":"tier_to_tierDetails","outputs":[{"internalType":"uint256","name":"amountOnSale","type":"uint256"},{"internalType":"uint256","name":"discount","type":"uint256"},{"internalType":"uint256","name":"lockupTime","type":"uint256"},{"internalType":"uint256","name":"purchaseCap","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum Tiers.Tier","name":"","type":"uint8"}],"name":"tier_to_tierPwc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum Tiers.Tier","name":"","type":"uint8"}],"name":"tier_to_totalContribution","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"}],"name":"totalAmountBought","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"}],"name":"totalContribution","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":"unpause","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newPauser","type":"address"}],"name":"updatePauser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"withdrawEth","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]