编译器
0.8.25+commit.b61c2a91
文件 1 的 12:ABDKMath64x64.sol
pragma solidity ^0.8.0;
library ABDKMath64x64 {
int128 private constant MIN_64x64 = -0x80000000000000000000000000000000;
int128 private constant MAX_64x64 = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
function fromInt (int256 x) internal pure returns (int128) {
unchecked {
require (x >= -0x8000000000000000 && x <= 0x7FFFFFFFFFFFFFFF);
return int128 (x << 64);
}
}
function toInt (int128 x) internal pure returns (int64) {
unchecked {
return int64 (x >> 64);
}
}
function fromUInt (uint256 x) internal pure returns (int128) {
unchecked {
require (x <= 0x7FFFFFFFFFFFFFFF);
return int128 (int256 (x << 64));
}
}
function toUInt (int128 x) internal pure returns (uint64) {
unchecked {
require (x >= 0);
return uint64 (uint128 (x >> 64));
}
}
function from128x128 (int256 x) internal pure returns (int128) {
unchecked {
int256 result = x >> 64;
require (result >= MIN_64x64 && result <= MAX_64x64);
return int128 (result);
}
}
function to128x128 (int128 x) internal pure returns (int256) {
unchecked {
return int256 (x) << 64;
}
}
function add (int128 x, int128 y) internal pure returns (int128) {
unchecked {
int256 result = int256(x) + y;
require (result >= MIN_64x64 && result <= MAX_64x64);
return int128 (result);
}
}
function sub (int128 x, int128 y) internal pure returns (int128) {
unchecked {
int256 result = int256(x) - y;
require (result >= MIN_64x64 && result <= MAX_64x64);
return int128 (result);
}
}
function mul (int128 x, int128 y) internal pure returns (int128) {
unchecked {
int256 result = int256(x) * y >> 64;
require (result >= MIN_64x64 && result <= MAX_64x64);
return int128 (result);
}
}
function muli (int128 x, int256 y) internal pure returns (int256) {
unchecked {
if (x == MIN_64x64) {
require (y >= -0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF &&
y <= 0x1000000000000000000000000000000000000000000000000);
return -y << 63;
} else {
bool negativeResult = false;
if (x < 0) {
x = -x;
negativeResult = true;
}
if (y < 0) {
y = -y;
negativeResult = !negativeResult;
}
uint256 absoluteResult = mulu (x, uint256 (y));
if (negativeResult) {
require (absoluteResult <=
0x8000000000000000000000000000000000000000000000000000000000000000);
return -int256 (absoluteResult);
} else {
require (absoluteResult <=
0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
return int256 (absoluteResult);
}
}
}
}
function mulu (int128 x, uint256 y) internal pure returns (uint256) {
unchecked {
if (y == 0) return 0;
require (x >= 0);
uint256 lo = (uint256 (int256 (x)) * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) >> 64;
uint256 hi = uint256 (int256 (x)) * (y >> 128);
require (hi <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
hi <<= 64;
require (hi <=
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - lo);
return hi + lo;
}
}
function div (int128 x, int128 y) internal pure returns (int128) {
unchecked {
require (y != 0);
int256 result = (int256 (x) << 64) / y;
require (result >= MIN_64x64 && result <= MAX_64x64);
return int128 (result);
}
}
function divi (int256 x, int256 y) internal pure returns (int128) {
unchecked {
require (y != 0);
bool negativeResult = false;
if (x < 0) {
x = -x;
negativeResult = true;
}
if (y < 0) {
y = -y;
negativeResult = !negativeResult;
}
uint128 absoluteResult = divuu (uint256 (x), uint256 (y));
if (negativeResult) {
require (absoluteResult <= 0x80000000000000000000000000000000);
return -int128 (absoluteResult);
} else {
require (absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
return int128 (absoluteResult);
}
}
}
function divu (uint256 x, uint256 y) internal pure returns (int128) {
unchecked {
require (y != 0);
uint128 result = divuu (x, y);
require (result <= uint128 (MAX_64x64));
return int128 (result);
}
}
function neg (int128 x) internal pure returns (int128) {
unchecked {
require (x != MIN_64x64);
return -x;
}
}
function abs (int128 x) internal pure returns (int128) {
unchecked {
require (x != MIN_64x64);
return x < 0 ? -x : x;
}
}
function inv (int128 x) internal pure returns (int128) {
unchecked {
require (x != 0);
int256 result = int256 (0x100000000000000000000000000000000) / x;
require (result >= MIN_64x64 && result <= MAX_64x64);
return int128 (result);
}
}
function avg (int128 x, int128 y) internal pure returns (int128) {
unchecked {
return int128 ((int256 (x) + int256 (y)) >> 1);
}
}
function gavg (int128 x, int128 y) internal pure returns (int128) {
unchecked {
int256 m = int256 (x) * int256 (y);
require (m >= 0);
require (m <
0x4000000000000000000000000000000000000000000000000000000000000000);
return int128 (sqrtu (uint256 (m)));
}
}
function pow (int128 x, uint256 y) internal pure returns (int128) {
unchecked {
bool negative = x < 0 && y & 1 == 1;
uint256 absX = uint128 (x < 0 ? -x : x);
uint256 absResult;
absResult = 0x100000000000000000000000000000000;
if (absX <= 0x10000000000000000) {
absX <<= 63;
while (y != 0) {
if (y & 0x1 != 0) {
absResult = absResult * absX >> 127;
}
absX = absX * absX >> 127;
if (y & 0x2 != 0) {
absResult = absResult * absX >> 127;
}
absX = absX * absX >> 127;
if (y & 0x4 != 0) {
absResult = absResult * absX >> 127;
}
absX = absX * absX >> 127;
if (y & 0x8 != 0) {
absResult = absResult * absX >> 127;
}
absX = absX * absX >> 127;
y >>= 4;
}
absResult >>= 64;
} else {
uint256 absXShift = 63;
if (absX < 0x1000000000000000000000000) { absX <<= 32; absXShift -= 32; }
if (absX < 0x10000000000000000000000000000) { absX <<= 16; absXShift -= 16; }
if (absX < 0x1000000000000000000000000000000) { absX <<= 8; absXShift -= 8; }
if (absX < 0x10000000000000000000000000000000) { absX <<= 4; absXShift -= 4; }
if (absX < 0x40000000000000000000000000000000) { absX <<= 2; absXShift -= 2; }
if (absX < 0x80000000000000000000000000000000) { absX <<= 1; absXShift -= 1; }
uint256 resultShift = 0;
while (y != 0) {
require (absXShift < 64);
if (y & 0x1 != 0) {
absResult = absResult * absX >> 127;
resultShift += absXShift;
if (absResult > 0x100000000000000000000000000000000) {
absResult >>= 1;
resultShift += 1;
}
}
absX = absX * absX >> 127;
absXShift <<= 1;
if (absX >= 0x100000000000000000000000000000000) {
absX >>= 1;
absXShift += 1;
}
y >>= 1;
}
require (resultShift < 64);
absResult >>= 64 - resultShift;
}
int256 result = negative ? -int256 (absResult) : int256 (absResult);
require (result >= MIN_64x64 && result <= MAX_64x64);
return int128 (result);
}
}
function sqrt (int128 x) internal pure returns (int128) {
unchecked {
require (x >= 0);
return int128 (sqrtu (uint256 (int256 (x)) << 64));
}
}
function log_2 (int128 x) internal pure returns (int128) {
unchecked {
require (x > 0);
int256 msb = 0;
int256 xc = x;
if (xc >= 0x10000000000000000) { xc >>= 64; msb += 64; }
if (xc >= 0x100000000) { xc >>= 32; msb += 32; }
if (xc >= 0x10000) { xc >>= 16; msb += 16; }
if (xc >= 0x100) { xc >>= 8; msb += 8; }
if (xc >= 0x10) { xc >>= 4; msb += 4; }
if (xc >= 0x4) { xc >>= 2; msb += 2; }
if (xc >= 0x2) msb += 1;
int256 result = msb - 64 << 64;
uint256 ux = uint256 (int256 (x)) << uint256 (127 - msb);
for (int256 bit = 0x8000000000000000; bit > 0; bit >>= 1) {
ux *= ux;
uint256 b = ux >> 255;
ux >>= 127 + b;
result += bit * int256 (b);
}
return int128 (result);
}
}
function ln (int128 x) internal pure returns (int128) {
unchecked {
require (x > 0);
return int128 (int256 (
uint256 (int256 (log_2 (x))) * 0xB17217F7D1CF79ABC9E3B39803F2F6AF >> 128));
}
}
function exp_2 (int128 x) internal pure returns (int128) {
unchecked {
require (x < 0x400000000000000000);
if (x < -0x400000000000000000) return 0;
uint256 result = 0x80000000000000000000000000000000;
if (x & 0x8000000000000000 > 0)
result = result * 0x16A09E667F3BCC908B2FB1366EA957D3E >> 128;
if (x & 0x4000000000000000 > 0)
result = result * 0x1306FE0A31B7152DE8D5A46305C85EDEC >> 128;
if (x & 0x2000000000000000 > 0)
result = result * 0x1172B83C7D517ADCDF7C8C50EB14A791F >> 128;
if (x & 0x1000000000000000 > 0)
result = result * 0x10B5586CF9890F6298B92B71842A98363 >> 128;
if (x & 0x800000000000000 > 0)
result = result * 0x1059B0D31585743AE7C548EB68CA417FD >> 128;
if (x & 0x400000000000000 > 0)
result = result * 0x102C9A3E778060EE6F7CACA4F7A29BDE8 >> 128;
if (x & 0x200000000000000 > 0)
result = result * 0x10163DA9FB33356D84A66AE336DCDFA3F >> 128;
if (x & 0x100000000000000 > 0)
result = result * 0x100B1AFA5ABCBED6129AB13EC11DC9543 >> 128;
if (x & 0x80000000000000 > 0)
result = result * 0x10058C86DA1C09EA1FF19D294CF2F679B >> 128;
if (x & 0x40000000000000 > 0)
result = result * 0x1002C605E2E8CEC506D21BFC89A23A00F >> 128;
if (x & 0x20000000000000 > 0)
result = result * 0x100162F3904051FA128BCA9C55C31E5DF >> 128;
if (x & 0x10000000000000 > 0)
result = result * 0x1000B175EFFDC76BA38E31671CA939725 >> 128;
if (x & 0x8000000000000 > 0)
result = result * 0x100058BA01FB9F96D6CACD4B180917C3D >> 128;
if (x & 0x4000000000000 > 0)
result = result * 0x10002C5CC37DA9491D0985C348C68E7B3 >> 128;
if (x & 0x2000000000000 > 0)
result = result * 0x1000162E525EE054754457D5995292026 >> 128;
if (x & 0x1000000000000 > 0)
result = result * 0x10000B17255775C040618BF4A4ADE83FC >> 128;
if (x & 0x800000000000 > 0)
result = result * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB >> 128;
if (x & 0x400000000000 > 0)
result = result * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9 >> 128;
if (x & 0x200000000000 > 0)
result = result * 0x10000162E43F4F831060E02D839A9D16D >> 128;
if (x & 0x100000000000 > 0)
result = result * 0x100000B1721BCFC99D9F890EA06911763 >> 128;
if (x & 0x80000000000 > 0)
result = result * 0x10000058B90CF1E6D97F9CA14DBCC1628 >> 128;
if (x & 0x40000000000 > 0)
result = result * 0x1000002C5C863B73F016468F6BAC5CA2B >> 128;
if (x & 0x20000000000 > 0)
result = result * 0x100000162E430E5A18F6119E3C02282A5 >> 128;
if (x & 0x10000000000 > 0)
result = result * 0x1000000B1721835514B86E6D96EFD1BFE >> 128;
if (x & 0x8000000000 > 0)
result = result * 0x100000058B90C0B48C6BE5DF846C5B2EF >> 128;
if (x & 0x4000000000 > 0)
result = result * 0x10000002C5C8601CC6B9E94213C72737A >> 128;
if (x & 0x2000000000 > 0)
result = result * 0x1000000162E42FFF037DF38AA2B219F06 >> 128;
if (x & 0x1000000000 > 0)
result = result * 0x10000000B17217FBA9C739AA5819F44F9 >> 128;
if (x & 0x800000000 > 0)
result = result * 0x1000000058B90BFCDEE5ACD3C1CEDC823 >> 128;
if (x & 0x400000000 > 0)
result = result * 0x100000002C5C85FE31F35A6A30DA1BE50 >> 128;
if (x & 0x200000000 > 0)
result = result * 0x10000000162E42FF0999CE3541B9FFFCF >> 128;
if (x & 0x100000000 > 0)
result = result * 0x100000000B17217F80F4EF5AADDA45554 >> 128;
if (x & 0x80000000 > 0)
result = result * 0x10000000058B90BFBF8479BD5A81B51AD >> 128;
if (x & 0x40000000 > 0)
result = result * 0x1000000002C5C85FDF84BD62AE30A74CC >> 128;
if (x & 0x20000000 > 0)
result = result * 0x100000000162E42FEFB2FED257559BDAA >> 128;
if (x & 0x10000000 > 0)
result = result * 0x1000000000B17217F7D5A7716BBA4A9AE >> 128;
if (x & 0x8000000 > 0)
result = result * 0x100000000058B90BFBE9DDBAC5E109CCE >> 128;
if (x & 0x4000000 > 0)
result = result * 0x10000000002C5C85FDF4B15DE6F17EB0D >> 128;
if (x & 0x2000000 > 0)
result = result * 0x1000000000162E42FEFA494F1478FDE05 >> 128;
if (x & 0x1000000 > 0)
result = result * 0x10000000000B17217F7D20CF927C8E94C >> 128;
if (x & 0x800000 > 0)
result = result * 0x1000000000058B90BFBE8F71CB4E4B33D >> 128;
if (x & 0x400000 > 0)
result = result * 0x100000000002C5C85FDF477B662B26945 >> 128;
if (x & 0x200000 > 0)
result = result * 0x10000000000162E42FEFA3AE53369388C >> 128;
if (x & 0x100000 > 0)
result = result * 0x100000000000B17217F7D1D351A389D40 >> 128;
if (x & 0x80000 > 0)
result = result * 0x10000000000058B90BFBE8E8B2D3D4EDE >> 128;
if (x & 0x40000 > 0)
result = result * 0x1000000000002C5C85FDF4741BEA6E77E >> 128;
if (x & 0x20000 > 0)
result = result * 0x100000000000162E42FEFA39FE95583C2 >> 128;
if (x & 0x10000 > 0)
result = result * 0x1000000000000B17217F7D1CFB72B45E1 >> 128;
if (x & 0x8000 > 0)
result = result * 0x100000000000058B90BFBE8E7CC35C3F0 >> 128;
if (x & 0x4000 > 0)
result = result * 0x10000000000002C5C85FDF473E242EA38 >> 128;
if (x & 0x2000 > 0)
result = result * 0x1000000000000162E42FEFA39F02B772C >> 128;
if (x & 0x1000 > 0)
result = result * 0x10000000000000B17217F7D1CF7D83C1A >> 128;
if (x & 0x800 > 0)
result = result * 0x1000000000000058B90BFBE8E7BDCBE2E >> 128;
if (x & 0x400 > 0)
result = result * 0x100000000000002C5C85FDF473DEA871F >> 128;
if (x & 0x200 > 0)
result = result * 0x10000000000000162E42FEFA39EF44D91 >> 128;
if (x & 0x100 > 0)
result = result * 0x100000000000000B17217F7D1CF79E949 >> 128;
if (x & 0x80 > 0)
result = result * 0x10000000000000058B90BFBE8E7BCE544 >> 128;
if (x & 0x40 > 0)
result = result * 0x1000000000000002C5C85FDF473DE6ECA >> 128;
if (x & 0x20 > 0)
result = result * 0x100000000000000162E42FEFA39EF366F >> 128;
if (x & 0x10 > 0)
result = result * 0x1000000000000000B17217F7D1CF79AFA >> 128;
if (x & 0x8 > 0)
result = result * 0x100000000000000058B90BFBE8E7BCD6D >> 128;
if (x & 0x4 > 0)
result = result * 0x10000000000000002C5C85FDF473DE6B2 >> 128;
if (x & 0x2 > 0)
result = result * 0x1000000000000000162E42FEFA39EF358 >> 128;
if (x & 0x1 > 0)
result = result * 0x10000000000000000B17217F7D1CF79AB >> 128;
result >>= uint256 (int256 (63 - (x >> 64)));
require (result <= uint256 (int256 (MAX_64x64)));
return int128 (int256 (result));
}
}
function exp (int128 x) internal pure returns (int128) {
unchecked {
require (x < 0x400000000000000000);
if (x < -0x400000000000000000) return 0;
return exp_2 (
int128 (int256 (x) * 0x171547652B82FE1777D0FFDA0D23A7D12 >> 128));
}
}
function divuu (uint256 x, uint256 y) private pure returns (uint128) {
unchecked {
require (y != 0);
uint256 result;
if (x <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
result = (x << 64) / y;
else {
uint256 msb = 192;
uint256 xc = x >> 192;
if (xc >= 0x100000000) { xc >>= 32; msb += 32; }
if (xc >= 0x10000) { xc >>= 16; msb += 16; }
if (xc >= 0x100) { xc >>= 8; msb += 8; }
if (xc >= 0x10) { xc >>= 4; msb += 4; }
if (xc >= 0x4) { xc >>= 2; msb += 2; }
if (xc >= 0x2) msb += 1;
result = (x << 255 - msb) / ((y - 1 >> msb - 191) + 1);
require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
uint256 hi = result * (y >> 128);
uint256 lo = result * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
uint256 xh = x >> 192;
uint256 xl = x << 64;
if (xl < lo) xh -= 1;
xl -= lo;
lo = hi << 128;
if (xl < lo) xh -= 1;
xl -= lo;
result += xh == hi >> 128 ? xl / y : 1;
}
require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
return uint128 (result);
}
}
function sqrtu (uint256 x) private pure returns (uint128) {
unchecked {
if (x == 0) return 0;
else {
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 >= 0x4) { 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 uint128 (r < r1 ? r : r1);
}
}
}
}
文件 2 的 12: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;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
文件 3 的 12:Game.sol
pragma solidity ^0.8.25;
import '@openzeppelin/contracts/access/Ownable.sol';
import "abdk-libraries-solidity/ABDKMath64x64.sol";
contract Game is Ownable {
using ABDKMath64x64 for int128;
struct Variable {
uint256 value;
bool isRenounced;
}
struct FreezerConfig {
int128 expoRate;
uint256 capacity;
uint256 basePrice;
uint256 _nextMintCost;
}
mapping(string => Variable) public variables;
FreezerConfig[] public freezers;
uint256[] public rentalPrices;
event VariableChanged(string indexed name, uint256 newValue);
event VariableRenounced(string indexed name);
event FreezerChanged(uint256 index, uint256 capacity, uint256 basePrice, uint256 expoRateBips);
event RentalPriceChanged(uint256 index, uint256 soupPerSecond);
constructor() {
set('minBatchSize', 50);
set('maxBatchSize', 250);
set('lpRewardBips', 2700);
set('sssRewardBips', 300);
set('lpLockDuration', 24 hours);
set('sssLockDuration', 24 hours);
set('freezerCapacity', 320);
set('publicDepositsEnabled', 0);
set('batchDefrostTime', 3 days);
set('freezerGracePeriod', 7 days);
set('rewardRetrievalDuration', 7 days);
set('liquiditySlippage', 95);
setRentalPrice(0, 30);
setRentalPrice(1, 50);
setRentalPrice(2, 100);
setFreezer(0, 10, 1 ether, 50);
setFreezer(1, 25, 2 ether, 75);
setFreezer(2, 50, 3 ether, 100);
}
modifier notRenounced(string memory name) {
require(!variables[name].isRenounced, "Variable has been renounced");
_;
}
function freezerCount() public view returns (uint256) {
return freezers.length;
}
function rentalPriceCount() public view returns (uint256) {
return rentalPrices.length;
}
function getRentalPrice(uint256 index) public view returns (uint256){
require(index < rentalPrices.length, "Invalid rental price index");
return rentalPrices[index];
}
function setRentalPrice(uint256 index, uint256 soupPerSecond) public notRenounced('rentalPrices') onlyOwner {
require(index <= rentalPrices.length, "Invalid index");
if (rentalPrices.length == index) rentalPrices.push();
rentalPrices[index] = soupPerSecond;
emit RentalPriceChanged(index, soupPerSecond);
}
function getFreezer(uint256 freezerIndex) public view returns (FreezerConfig memory) {
require(freezerIndex < freezers.length, "Invalid freezer size");
return freezers[freezerIndex];
}
function setFreezer(uint256 index, uint256 capacity, uint256 basePrice, uint256 expoRateBips) public notRenounced('freezers') onlyOwner {
require(index <= freezers.length, "Invalid index");
if (freezers.length == index) freezers.push();
freezers[index].capacity = capacity;
freezers[index].basePrice = basePrice;
int128 one = ABDKMath64x64.fromUInt(1);
freezers[index].expoRate = one.add(ABDKMath64x64.divu(expoRateBips, 10000));
emit FreezerChanged(index, capacity, basePrice, expoRateBips);
}
function set(string memory name, uint256 newValue) public notRenounced(name) onlyOwner {
variables[name].value = newValue;
emit VariableChanged(name, newValue);
}
function renounce(string memory name) external notRenounced(name) onlyOwner {
variables[name].isRenounced = true;
emit VariableRenounced(name);
}
function get(string memory name) external view returns (uint256) {
return variables[name].value;
}
function isRenounced(string memory name) external view returns (bool) {
return variables[name].isRenounced;
}
}
文件 4 的 12: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);
}
文件 5 的 12:ILiquidityPot.sol
pragma solidity ^0.8.22;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface ILiquidityPot {
function router() external returns (address);
function wethAddress() external returns (address);
function stakingToken() external returns (IERC20);
function stakeFor(address user, uint256 amount) external;
}
文件 6 的 12:ISoup.sol
pragma solidity ^0.8.22;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface ISoup is IERC20 {
function debase() external;
function burn(uint256 amount) external;
function freeze(uint256 amount) external;
function mint(address to, uint256 amount) external;
function deflationRate() external returns (int128);
function requestRewards(uint256 rewardBips) external;
function totalLiquidSupply() external view returns (uint256);
function accountForDefrostedDeflation(uint256 leftover) external;
function unfreeze(address to, uint256 amount) external returns (bool);
function soupToFragment(uint256 soup) external view returns (uint256);
function fragmentToSoup(uint256 value) external view returns (uint256);
function balanceOfUnderlying(address who) external view returns (uint256);
function transferUnderlying(address to, uint256 value) external returns (bool);
}
文件 7 的 12:IUniswapV2Router01.sol
pragma solidity >=0.6.2;
interface IUniswapV2Router01 {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB, uint liquidity);
function addLiquidityETH(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external payable returns (uint amountToken, uint amountETH, uint liquidity);
function removeLiquidity(
address tokenA,
address tokenB,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB);
function removeLiquidityETH(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external returns (uint amountToken, uint amountETH);
function removeLiquidityWithPermit(
address tokenA,
address tokenB,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountA, uint amountB);
function removeLiquidityETHWithPermit(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountToken, uint amountETH);
function swapExactTokensForTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
function swapTokensForExactTokens(
uint amountOut,
uint amountInMax,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
external
payable
returns (uint[] memory amounts);
function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
external
returns (uint[] memory amounts);
function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
external
returns (uint[] memory amounts);
function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
external
payable
returns (uint[] memory amounts);
function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
}
文件 8 的 12:IUniswapV2Router02.sol
pragma solidity >=0.6.2;
import './IUniswapV2Router01.sol';
interface IUniswapV2Router02 is IUniswapV2Router01 {
function removeLiquidityETHSupportingFeeOnTransferTokens(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external returns (uint amountETH);
function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountETH);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external payable;
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
}
文件 9 的 12:Math.sol
pragma solidity ^0.8.0;
library Math {
enum Rounding {
Down,
Up,
Zero
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
return a == 0 ? 0 : (a - 1) / b + 1;
}
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
uint256 prod0;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
return prod0 / denominator;
}
require(denominator > prod1, "Math: mulDiv overflow");
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (~denominator + 1);
assembly {
denominator := div(denominator, twos)
prod0 := div(prod0, twos)
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
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;
return result;
}
}
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 result = 1 << (log2(a) >> 1);
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}
文件 10 的 12: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);
}
}
文件 11 的 12: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;
}
}
文件 12 的 12:SingleSidedSoup.sol
pragma solidity ^0.8.0;
import './Game.sol';
import './interfaces/ISoup.sol';
import './interfaces/ILiquidityPot.sol';
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/Math.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import '@openzeppelin/contracts/security/ReentrancyGuard.sol';
import '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';
contract SingleSidedSoup is Ownable, ReentrancyGuard {
IUniswapV2Router02 public router;
address public wethAddress;
uint256 public constant PRECISION = 10**10;
uint256 public rewardDuration = 7 days;
uint256 public totalUnderlyingStaked;
uint256 public nextRewardRetrieval;
uint256 public rewardsPerSecond;
uint256 public claimableBalance;
uint256 public rewardsPerStake;
uint256 public rewardEndTime;
uint256 public totalStaked;
uint256 public updatedAt;
Game public game;
ISoup public soup;
ILiquidityPot public liquidityPot;
mapping(address => uint256) unlockAt;
struct Stake {
uint256 excluded;
uint256 underlyingAmount;
}
struct UserInfo {
uint256 stakingTokenBalance;
uint256 userAllocatedAmount;
uint256 nextRewardRetrieval;
uint256 userStakedAmount;
uint256 rewardsPerSecond;
uint256 rewardsPerStake;
uint256 rewardEndTime;
uint256 lockDuration;
uint256 totalStaked;
uint256 unlockAt;
}
mapping(address => Stake) public stakes;
event Staked(address indexed user, uint256 amount, uint256 underlyingAmount);
event Withdrawn(address indexed user, uint256 amount);
event RewardClaimed(address indexed user, uint256 reward);
event AddedToLiquidityPot(address indexed user, uint256 lpAmount, uint256 soupAmount, uint256 ethAmount);
event EpochDurationUpdated(uint256 duration);
event RewardDurationUpdated(uint256 duration);
event RewardsUpdated(uint256 rewardsPerSecond);
constructor(ISoup _soup, Game _game, ILiquidityPot _liquidityPot) {
game = _game;
soup = _soup;
liquidityPot = _liquidityPot;
wethAddress = liquidityPot.wethAddress();
router = IUniswapV2Router02(liquidityPot.router());
}
function getInfo(address user) public view returns (UserInfo memory) {
uint256 userAllocatedAmount;
uint256 stakingTokenBalance;
uint256 userStakedAmount;
uint256 unlocksAt;
if (user != address(0)) {
unlocksAt = unlockAt[user];
stakingTokenBalance = soup.balanceOf(user);
userAllocatedAmount = allocatedAmount(user);
userStakedAmount = soup.soupToFragment(stakes[user].underlyingAmount);
}
return UserInfo({
totalStaked: soup.soupToFragment(totalStaked),
lockDuration: game.get('sssLockDuration'),
userAllocatedAmount: userAllocatedAmount,
stakingTokenBalance: stakingTokenBalance,
nextRewardRetrieval: nextRewardRetrieval,
userStakedAmount: userStakedAmount,
rewardsPerSecond: rewardsPerSecond,
rewardsPerStake: rewardsPerStake,
rewardEndTime: rewardEndTime,
unlockAt: unlocksAt
});
}
function setRewardDuration(uint256 _rewardDuration) external onlyOwner {
require(_rewardDuration <= 2 weeks, "Reward duration must be less than 2 weeks");
require(_rewardDuration > 1 days, "Reward duration must not be 1 day");
rewardDuration = _rewardDuration;
emit RewardDurationUpdated(_rewardDuration);
}
function stake(uint256 amount) external {
stakeFor(msg.sender, amount);
}
function stakeFor(address user, uint256 _amount) public nonReentrant {
require(game.get('publicDepositsEnabled') > 0, "deposits disabled");
require(_amount > 0, "Cannot stake 0");
unlockAt[user] = block.timestamp + game.get('sssLockDuration');
uint256 underlyingAmount = soup.fragmentToSoup(_amount);
totalUnderlyingStaked += underlyingAmount;
soup.transferFrom(msg.sender, address(this), _amount);
bool isFirstStake = totalStaked == 0;
_claim(user);
totalStaked += underlyingAmount;
stakes[user].underlyingAmount += underlyingAmount;
if (isFirstStake) _retrieveAndReward();
emit Staked(user, _amount, underlyingAmount);
}
function withdraw(uint256 _amount) external nonReentrant {
require(unlockAt[msg.sender] < block.timestamp, 'tokens not yet unlocked');
unlockAt[msg.sender] = block.timestamp + game.get('sssLockDuration');
uint256 underlyingAmount = soup.fragmentToSoup(_amount);
require(underlyingAmount <= stakes[msg.sender].underlyingAmount, "Withdraw amount exceeds balance");
_claim(msg.sender);
totalStaked -= underlyingAmount;
totalUnderlyingStaked -= underlyingAmount;
stakes[msg.sender].underlyingAmount -= underlyingAmount;
soup.transferUnderlying(msg.sender, underlyingAmount);
emit Withdrawn(msg.sender, _amount);
}
function claim() external nonReentrant {
_claim(msg.sender);
}
function _claim(address user) internal {
uint256 reward = allocatedUnderlyingAmount(user) / PRECISION;
unlockAt[user] = block.timestamp + game.get('sssLockDuration');
if (block.timestamp >= nextRewardRetrieval && totalStaked > 0)
_retrieveAndReward();
else updateRewards();
claimableBalance -= reward;
stakes[user].excluded = rewardsPerStake;
if (reward > 0) {
soup.transferUnderlying(user, reward);
emit RewardClaimed(user, soup.soupToFragment(reward));
}
soup.debase();
}
function retrieveAndReward() external nonReentrant {
require(totalStaked > 0, "Can not update rewards until users have staked");
if (rewardsPerSecond != 0)
require(block.timestamp >= nextRewardRetrieval, "Cannot update rewards yet");
_retrieveAndReward();
}
function updateRewards() internal {
if (totalStaked == 0) return;
uint256 currentAllocation = currentAllocationPeriod() * rewardsPerSecond;
rewardsPerStake += currentAllocation / totalStaked;
claimableBalance += currentAllocation / PRECISION;
updatedAt = block.timestamp;
emit RewardsUpdated(rewardsPerSecond);
}
function _retrieveAndReward() internal {
nextRewardRetrieval = block.timestamp + rewardDuration;
try soup.requestRewards(game.get('sssRewardBips')) { } catch { }
uint256 balance = soup.balanceOfUnderlying(address(this));
updateRewards();
int256 remainder = int256(balance) - int256(totalUnderlyingStaked) - int256(claimableBalance);
if (remainder <= 0) rewardsPerSecond = 0;
else rewardsPerSecond = PRECISION * uint256(remainder) / rewardDuration;
rewardEndTime = rewardDuration + block.timestamp;
}
function allocatedAmount(address user) public view returns (uint256) {
return soup.soupToFragment(allocatedUnderlyingAmount(user) / PRECISION);
}
function allocatedUnderlyingAmount(address user) public view returns (uint256) {
if (totalStaked == 0) return 0;
uint256 currentAllocation = currentAllocationPeriod() * rewardsPerSecond * stakes[user].underlyingAmount / totalStaked;
uint256 previousAllocation = stakes[user].underlyingAmount * (rewardsPerStake - stakes[user].excluded);
return (previousAllocation + currentAllocation);
}
function currentAllocationPeriod() public view returns (uint256) {
if (rewardEndTime <= updatedAt) return 0;
return Math.min(rewardEndTime, block.timestamp) - updatedAt;
}
function compound() external payable {
unlockAt[msg.sender] = block.timestamp + game.get('sssLockDuration');
uint256 underlyingReward = allocatedUnderlyingAmount(msg.sender) / PRECISION;
require(underlyingReward > 0, 'nothing to compound');
if (block.timestamp >= nextRewardRetrieval)
_retrieveAndReward();
else updateRewards();
claimableBalance -= underlyingReward;
totalUnderlyingStaked += underlyingReward;
stakes[msg.sender].excluded = rewardsPerStake;
totalStaked += underlyingReward;
stakes[msg.sender].underlyingAmount += underlyingReward;
emit Staked(msg.sender, soup.soupToFragment(underlyingReward), underlyingReward);
soup.debase();
}
function compoundRewardToLiquidityPot() external payable {
uint256 underlyingReward = allocatedUnderlyingAmount(msg.sender) / PRECISION;
require(underlyingReward > 0, 'nothing to compound');
if (block.timestamp >= nextRewardRetrieval)
_retrieveAndReward();
else updateRewards();
claimableBalance -= underlyingReward;
stakes[msg.sender].excluded = rewardsPerStake;
address[] memory path = new address[](2);
path[0] = wethAddress; path[1] = address(soup);
uint256[] memory amounts = router.getAmountsOut(msg.value, path);
uint256 reward = soup.soupToFragment(underlyingReward);
require(amounts[1] > (reward * liquiditySlippage())/100,
'Supplied ETH should be worth the reward amount after slippage is applied');
_addLiquidity(reward, address(this));
IERC20 lpToken = liquidityPot.stakingToken();
uint256 lpBalance = lpToken.balanceOf(address(this));
lpToken.approve(address(liquidityPot), lpBalance);
liquidityPot.stakeFor(msg.sender, lpBalance);
emit AddedToLiquidityPot(msg.sender, lpBalance, reward, msg.value);
soup.debase();
}
function liquiditySlippage() public view returns (uint256) {
return game.get('liquiditySlippage');
}
function _addLiquidity(uint256 soupAmount, address recipient) internal {
soup.approve(address(router), soupAmount);
router.addLiquidityETH{ value: address(this).balance }(
address(soup),
soupAmount,
0,
0,
recipient,
block.timestamp + 1800
);
}
function emergencyWithdraw(uint256 amount) external nonReentrant {
require(unlockAt[msg.sender] <= block.timestamp, "tokens not yet unlocked");
uint256 underlyingAmount = soup.fragmentToSoup(amount);
require(underlyingAmount <= stakes[msg.sender].underlyingAmount, "Withdraw exceeds staked balance");
stakes[msg.sender].excluded = rewardsPerStake;
totalStaked -= underlyingAmount;
totalUnderlyingStaked -= underlyingAmount;
stakes[msg.sender].underlyingAmount -= underlyingAmount;
soup.transferUnderlying(msg.sender, underlyingAmount);
emit Withdrawn(msg.sender, amount);
}
receive() external payable {}
fallback() external payable {}
}
{
"compilationTarget": {
"project:/contracts/SingleSidedSoup.sol": "SingleSidedSoup"
},
"evmVersion": "cancun",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [],
"viaIR": true
}
[{"inputs":[{"internalType":"contract ISoup","name":"_soup","type":"address"},{"internalType":"contract Game","name":"_game","type":"address"},{"internalType":"contract ILiquidityPot","name":"_liquidityPot","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"lpAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"soupAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethAmount","type":"uint256"}],"name":"AddedToLiquidityPot","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"}],"name":"EpochDurationUpdated","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":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"}],"name":"RewardDurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"rewardsPerSecond","type":"uint256"}],"name":"RewardsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"underlyingAmount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"allocatedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"allocatedUnderlyingAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimableBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"compound","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"compoundRewardToLiquidityPot","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"currentAllocationPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"game","outputs":[{"internalType":"contract Game","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getInfo","outputs":[{"components":[{"internalType":"uint256","name":"stakingTokenBalance","type":"uint256"},{"internalType":"uint256","name":"userAllocatedAmount","type":"uint256"},{"internalType":"uint256","name":"nextRewardRetrieval","type":"uint256"},{"internalType":"uint256","name":"userStakedAmount","type":"uint256"},{"internalType":"uint256","name":"rewardsPerSecond","type":"uint256"},{"internalType":"uint256","name":"rewardsPerStake","type":"uint256"},{"internalType":"uint256","name":"rewardEndTime","type":"uint256"},{"internalType":"uint256","name":"lockDuration","type":"uint256"},{"internalType":"uint256","name":"totalStaked","type":"uint256"},{"internalType":"uint256","name":"unlockAt","type":"uint256"}],"internalType":"struct SingleSidedSoup.UserInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidityPot","outputs":[{"internalType":"contract ILiquidityPot","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquiditySlippage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextRewardRetrieval","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":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"retrieveAndReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardEndTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsPerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsPerStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rewardDuration","type":"uint256"}],"name":"setRewardDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"soup","outputs":[{"internalType":"contract ISoup","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"stakeFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stakes","outputs":[{"internalType":"uint256","name":"excluded","type":"uint256"},{"internalType":"uint256","name":"underlyingAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalUnderlyingStaked","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":"updatedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wethAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]