diff --git a/contracts/Mocks/WsysMock.sol b/contracts/Mocks/WsysMock.sol new file mode 100644 index 0000000..2f2a66e --- /dev/null +++ b/contracts/Mocks/WsysMock.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.18; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; + +contract WsysMock is ERC20, Ownable, ERC20Burnable { + constructor(string memory name, string memory symbol, uint256 initialAmount) ERC20(name, symbol) Ownable(msg.sender) { + _mint(msg.sender, initialAmount); + } + + function mint(address to, uint256 amount) public onlyOwner { + _mint(to, amount); + } + + function decimals() public pure override returns (uint8) { + return 18; + } +} diff --git a/contracts/SingleSidedInsurancePool.sol b/contracts/SingleSidedInsurancePool.sol index 36762ff..c73836f 100644 --- a/contracts/SingleSidedInsurancePool.sol +++ b/contracts/SingleSidedInsurancePool.sol @@ -291,8 +291,14 @@ contract SingleSidedInsurancePool is uint256 unoReward = blocks * poolInfo.unoMultiplierPerBlock; accUnoPerShare = accUnoPerShare + (unoReward * ACC_UNO_PRECISION) / tokenSupply; } - uint256 userBalance = userInfo[_to].amount; - pending = (userBalance * uint256(accUnoPerShare)) / ACC_UNO_PRECISION - userInfo[_to].rewardDebt; + (uint256 pendingAmount,,) = IRiskPool(riskPool).getWithdrawRequest(_to); + uint256 userBalance = userInfo[_to].amount - pendingAmount; + if(userBalance == 0){ + pending = 0; + } + else { + pending = (userBalance * uint256(accUnoPerShare)) / ACC_UNO_PRECISION - userInfo[_to].rewardDebt; + } } /** @@ -550,13 +556,11 @@ contract SingleSidedInsurancePool is } function _updateReward(address _to) internal returns (uint256, uint256) { - uint256 requestTime; - (, requestTime, ) = IRiskPool(riskPool).getWithdrawRequest(_to); - if (requestTime > 0) { - return (0, 0); + (uint256 pendingAmount,,) = IRiskPool(riskPool).getWithdrawRequest(_to); + uint256 amount = userInfo[_to].amount - pendingAmount; + if(amount == 0){ + return (0,0); } - - uint256 amount = userInfo[_to].amount; uint256 accumulatedUno = (amount * uint256(poolInfo.accUnoPerShare)) / ACC_UNO_PRECISION; uint256 _pendingUno = accumulatedUno - userInfo[_to].rewardDebt; diff --git a/test/foundry/NewMCRRollux.t.sol b/test/foundry/NewMCRRollux.t.sol deleted file mode 100644 index 90d87c8..0000000 --- a/test/foundry/NewMCRRollux.t.sol +++ /dev/null @@ -1,372 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.23; - -import "../../contracts/Mocks/MockUNO.sol"; -import "../../contracts/Mocks/USDCRollux.sol"; -import "../../contracts/Mocks/SupraPriceOracle.sol"; -import "../../contracts/SingleSidedInsurancePool.sol"; -import "../../contracts/Mocks/MockCapitalAgent.sol"; -import "../../contracts/ExchangeAgent.sol"; -import "../../contracts/uma/PayoutRequest.sol"; -import "../../contracts/factories/SalesPolicyFactory.sol"; -import "../../contracts/interfaces/ICapitalAgent.sol"; -import "../../contracts/SalesPolicy.sol"; - -import "lib/forge-std/src/Vm.sol"; -import "forge-std/console.sol"; - -import "lib/forge-std/src/Test.sol"; -import "../../src/TransparentProxy.sol"; - -contract NewMCRRollux is Test { - MockUNO uno; - USDCmock sys; - SupraPriceOracle priceFeed; - SingleSidedInsurancePool pool; - MockCapitalAgent capitalAgent; - TransparentProxy capitalAgentProxy; - MockCapitalAgent proxycapital; - ExchangeAgent exchange; - PayoutRequest payout; - SalesPolicyFactory salesFactory; - SalesPolicy salesPolicy; - - address user = address(1); - address user2 = address(2); - address user3 = address(3); - address user4 = address(4); - address user5 = address(5); - address user6 = address(6); - address user7 = address(7); - address user8 = address(8); - address user9 = address(9); - address admin = address(this); - address constant WSYS = 0x4200000000000000000000000000000000000006; - address constant USDC = 0x368433CaC2A0B8D76E64681a9835502a1f2A8A30; - address constant UNO = 0x570baA32dB74279a50491E88D712C957F4C9E409; - address constant PRICE = 0x14eF9C6cD5A8C78af407cEcCA3E4668e466F2B18; - address constant WSYSPOOL = 0x3B61743180857c9D898c336b1604f4742887aa74; - address constant SALES_FACTORY = 0xD86D9be9143Dc514340C73502f2B77d93d0B11f4; - uint256 constant MCR = 10000000; - uint256 constant MLR = 1000000; - address constant PREMIUM_POOL = 0xc94002a997d4e4E90D423778170588f695c5f242; - address constant PAYOUT = 0xCaB9faf23a9803352f3f61Bc23782A9eb4a90fcC; - address constant EXCHANGE_AGENT_ADDRESS = 0x83f618d714B9464C8e63F1d95592BaAa2d51a54E; - address constant SALES = 0x5B170693E096D8602f970757068859b9A117fA6D; - address constant MintAddress = 0x3ad22Ae2dE3dCF105E8DaA12acDd15bD47596863; - address constant SysMillionaire = 0x3F0e40bC7e9cb5f46E906dAEd18651Fb6212Aa8E; - address constant Multisig = 0x15E18e012cb6635b228e0DF0b6FC72627C8b2429; - - function setUp() public { - string memory CHAIN_URL = vm.envString("ROLLUXMAIN_URL"); - - vm.createSelectFork(CHAIN_URL); - priceFeed = SupraPriceOracle(PRICE); - - vm.createSelectFork(CHAIN_URL); - salesPolicy = SalesPolicy(payable(SALES)); - - vm.createSelectFork(CHAIN_URL); - salesFactory = SalesPolicyFactory(SALES_FACTORY); - - vm.createSelectFork(CHAIN_URL); - pool = SingleSidedInsurancePool(WSYSPOOL); - - vm.createSelectFork(CHAIN_URL); - sys = USDCmock(WSYS); - - vm.createSelectFork(CHAIN_URL); - exchange = ExchangeAgent(payable(EXCHANGE_AGENT_ADDRESS)); - - vm.createSelectFork(CHAIN_URL); - payout = PayoutRequest((PAYOUT)); - - capitalAgent = new MockCapitalAgent(); - capitalAgentProxy = new TransparentProxy(address(capitalAgent), address(this), ""); - proxycapital = MockCapitalAgent(address(capitalAgentProxy)); - proxycapital.initialize(address(exchange), USDC, address(this), address(this)); - proxycapital.setMCR(MCR); - proxycapital.setMLR(MLR); - proxycapital.setSalesPolicyFactory(SALES_FACTORY); - vm.prank(0x100c50947580d9158B7C26f79401404208CFbE62); - payout.setCapitalAgent(ICapitalAgent(address(proxycapital))); - - vm.prank(Multisig); - salesFactory.setCapitalAgentInPolicy(address(proxycapital)); - - vm.prank(Multisig); - pool.setCapitalAgent(address(proxycapital)); - proxycapital.addPoolByAdmin(address(pool), WSYS, 1000000); - } - - function setupUsersAndStakes(uint256 amount, uint256 amount2, uint256 amount3, uint256 amount4) internal { - vm.assume(amount > 0 && amount < 4000000000000000000000); //4k wsys - vm.assume(amount2 > 0 && amount2 < 4000000000000000000000); - vm.assume(amount3 > 0 && amount3 < 4000000000000000000000); - vm.assume(amount4 > 0 && amount4 < 4000000000000000000000); - - // Mint - vm.prank(SysMillionaire); - sys.transfer(address(user), 5000000000000000000000); //5k wsys - vm.prank(SysMillionaire); - sys.transfer(address(user2), amount); - vm.prank(SysMillionaire); - sys.transfer(address(user3), amount2); - vm.prank(SysMillionaire); - sys.transfer(address(user4), amount); - vm.prank(SysMillionaire); - sys.transfer(address(user5), amount2); - vm.prank(SysMillionaire); - sys.transfer(address(user6), amount4); - vm.prank(SysMillionaire); - sys.transfer(address(user7), amount); - vm.prank(SysMillionaire); - sys.transfer(address(user8), amount3); - vm.prank(SysMillionaire); - sys.transfer(address(user9), 10000000000000000000000); //10k wsys - // Approve - vm.prank(address(user)); - sys.approve(address(pool), 5000000000000000000000); - vm.prank(address(user2)); - sys.approve(address(pool), amount); - vm.prank(address(user3)); - sys.approve(address(pool), amount2); - vm.prank(address(user4)); - sys.approve(address(pool), amount); - vm.prank(address(user5)); - sys.approve(address(pool), amount2); - vm.prank(address(user6)); - sys.approve(address(pool), amount4); - vm.prank(address(user7)); - sys.approve(address(pool), amount); - vm.prank(address(user8)); - sys.approve(address(pool), amount3); - vm.prank(address(user9)); - sys.approve(address(pool), 10000000000000000000000); - - // Enter in pool - vm.prank(address(user)); - pool.enterInPool(5000000000000000000000); - vm.prank(address(user2)); - pool.enterInPool(amount); - vm.prank(address(user3)); - pool.enterInPool(amount2); - vm.prank(address(user4)); - pool.enterInPool(amount); - vm.prank(address(user5)); - pool.enterInPool(amount2); - vm.prank(address(user6)); - pool.enterInPool(amount4); - vm.prank(address(user7)); - pool.enterInPool(amount); - vm.prank(address(user8)); - pool.enterInPool(amount3); - vm.prank(address(user9)); - pool.enterInPool(10000000000000000000000); - } - - function setupStartWithdrawal(uint256 amount, uint256 amount2, uint256 amount3, uint256 amount4) internal { - vm.prank(address(user2)); - pool.leaveFromPoolInPending(amount); - vm.prank(address(user3)); - pool.leaveFromPoolInPending(amount2); - vm.prank(address(user4)); - pool.leaveFromPoolInPending(amount); - vm.prank(address(user5)); - pool.leaveFromPoolInPending(amount2); - vm.prank(address(user6)); - pool.leaveFromPoolInPending(amount4); - vm.prank(address(user7)); - pool.leaveFromPoolInPending(amount); - vm.prank(address(user8)); - pool.leaveFromPoolInPending(amount3); - vm.prank(address(user9)); - pool.leaveFromPoolInPending(10000000000000000000000); - } - - function setupFinishWithdrawal(uint256 amount, uint256 amount2, uint256 amount3, uint256 amount4) internal { - vm.prank(address(user2)); - pool.leaveFromPending(amount); - vm.prank(address(user3)); - pool.leaveFromPending(amount2); - vm.prank(address(user4)); - pool.leaveFromPending(amount); - vm.prank(address(user5)); - pool.leaveFromPending(amount2); - vm.prank(address(user6)); - pool.leaveFromPending(amount4); - vm.prank(address(user7)); - pool.leaveFromPending(amount); - vm.prank(address(user8)); - pool.leaveFromPending(amount3); - vm.prank(address(user9)); - pool.leaveFromPending(10000000000000000000000); - } - - function test_stake(uint256 amount) public { - vm.assume(0 < amount); - vm.assume(amount < 10000000000000000000000); - vm.prank(SysMillionaire); - sys.transfer(address(user), amount); - address riskPool = pool.riskPool(); - uint256 balanceBefore = sys.balanceOf(riskPool); - assertEq(sys.balanceOf(user), amount); - vm.prank(address(user)); - sys.approve(address(pool), amount); - vm.prank(address(user)); - pool.enterInPool(amount); - - assertEq(sys.balanceOf(address(riskPool)), (balanceBefore + amount)); - } - - function test_stakeWithdrawal(uint256 amount) public { - vm.assume(amount < 50000000000000000000000); - vm.assume(amount > 10000000000000000000000); - - vm.prank(SysMillionaire); - sys.transfer(address(user), amount); - assertEq(sys.balanceOf(user), amount); - - vm.prank(address(user)); - sys.approve(address(pool), amount); - - vm.prank(address(user)); - pool.enterInPool(amount); - - uint256 expectedValueBefore = proxycapital._convertTokenToUSDC(address(sys), amount); - assertEq(proxycapital.totalCapitalStaked(), expectedValueBefore); - - vm.prank(address(user)); - vm.expectRevert(); //should revert by the mcr, as he's the only one staked - pool.leaveFromPoolInPending(amount); - - vm.prank(address(user)); - pool.leaveFromPoolInPending(amount / 48); - - skip(950400); //11 days - - vm.prank(address(user)); - pool.leaveFromPending(amount / 48); - - assertEq(sys.balanceOf(user), (amount / 48)); - - uint256 expectedValue = proxycapital._convertTokenToUSDC(address(sys), amount - (amount / 48)); - - assertEq(proxycapital.totalCapitalStaked(), expectedValue); - } - - function test_initialSetupAndStaking(uint256 amount, uint256 amount2, uint256 amount3, uint256 amount4) public { - setupUsersAndStakes(amount, amount2, amount3, amount4); - - uint256 calcExpectedStake = 5000000000000000000000 + - (3 * amount) + - (2 * amount2) + - amount3 + - amount4 + - 10000000000000000000000; - - uint256 expectedStake = proxycapital._convertTokenToUSDC(address(sys), calcExpectedStake); - - assertEq(proxycapital.totalCapitalStaked(), expectedStake); - } - - function test_withdrawalProcess(uint256 amount, uint256 amount2, uint256 amount3, uint256 amount4) public { - test_initialSetupAndStaking(amount, amount2, amount3, amount4); - - vm.prank(address(user2)); - pool.leaveFromPoolInPending(amount); - vm.prank(address(user3)); - pool.leaveFromPoolInPending(amount2); - vm.prank(address(user4)); - pool.leaveFromPoolInPending(amount); - - skip(950400); //11 days - vm.prank(address(user2)); - pool.leaveFromPending(amount); - vm.prank(address(user3)); - pool.leaveFromPending(amount2); - vm.prank(address(user4)); - pool.leaveFromPending(amount); - - vm.prank(address(user)); - vm.expectRevert(); - pool.leaveFromPoolInPending(50000000000000000000000); - - vm.prank(address(user)); - pool.leaveFromPoolInPending(5000000000000000000000); - } - - function test_cantWithdrawAmountBelowMCR(uint256 amount, uint256 amount2, uint256 amount3, uint256 amount4) public { - setupUsersAndStakes(amount, amount2, amount3, amount4); - - uint256 stakedAfter = proxycapital.totalCapitalStaked(); - proxycapital.setMCR(stakedAfter / 2); - - vm.prank(SysMillionaire); - sys.transfer(address(user), 5000000000000); - vm.prank(address(user)); - sys.approve(address(pool), 5000000000000); - vm.prank(address(user)); - pool.enterInPool(500000000000); - - uint256 totalUserStaked = (500000000000 + 5000000000000000000000); - - //Here user will withdrawal all of his money and should not fail by the MCR - vm.prank(address(user)); - pool.leaveFromPoolInPending(500000000000); - skip(950400); //11 days - vm.prank(address(user)); - pool.leaveFromPending(500000000000); - - proxycapital.totalCapitalStaked(); - proxycapital.MCR(); - - //Here other users will withdrawal all of their money - setupStartWithdrawal(amount, amount2, amount3, amount4); - skip(950400); //11 days - setupFinishWithdrawal(amount, amount2, amount3, amount4); - - proxycapital.totalCapitalStaked(); - proxycapital.getPoolInfo(address(pool)); - proxycapital.MCR(); - - //Here user will withdrawal all of his money and it should fail by the MCR - vm.prank(address(user)); - vm.expectRevert(); - pool.leaveFromPoolInPending((totalUserStaked - 500000000000)); - } - - function test_shouldNotFailWithdrawalCompletion(uint256 amount, uint256 amount2, uint256 amount3, uint256 amount4) public { - setupUsersAndStakes(amount, amount2, amount3, amount4); - - uint256 stakedAfter = proxycapital.totalCapitalStaked(); - proxycapital.setMCR(stakedAfter / 2); - - vm.prank(SysMillionaire); - sys.transfer(address(user), 5000000000000); - vm.prank(address(user)); - sys.approve(address(pool), 5000000000000); - vm.prank(address(user)); - pool.enterInPool(500000000000); - - uint256 totalUserStaked = (500000000000 + 5000000000000000000000); - - proxycapital.totalCapitalStaked(); - proxycapital.totalCapitalStakedByCurrency(WSYS); - proxycapital.MCR(); - - //Here other users will start to withdrawal all of their money, but won't finish withdrawing yet - - setupStartWithdrawal(amount, amount2, amount3, amount4); - skip(950400); //11 days - - vm.prank(address(user)); - //this call should fail by the MCR as other users withdrew, but it doesn't - pool.leaveFromPoolInPending(totalUserStaked / 48); - skip(950400); //11 days - - vm.prank(address(user)); - pool.leaveFromPending(totalUserStaked / 48); - setupFinishWithdrawal(amount, amount2, amount3, amount4); - } -} diff --git a/test/foundry/RewardsTest.t.sol b/test/foundry/RewardsTest.t.sol new file mode 100644 index 0000000..63c2995 --- /dev/null +++ b/test/foundry/RewardsTest.t.sol @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity =0.8.23; + +import "../../contracts/Mocks/MockUNO.sol"; +import "../../contracts/Mocks/WsysMock.sol"; +import "../../contracts/Mocks/SupraPriceOracle.sol"; +import "../../contracts/SingleSidedInsurancePool.sol"; +import "../../contracts/CapitalAgent.sol"; +import "../../contracts/factories/RiskPoolFactory.sol"; +import "../../contracts/factories/RewarderFactory.sol"; +import "../../src/TransparentProxy.sol"; + +import "lib/forge-std/src/Vm.sol"; +import "forge-std/console.sol"; + +import "lib/forge-std/src/Test.sol"; + +contract RewardsTest is Test { + MockUNO uno; + WsysMock wsys; + SingleSidedInsurancePool pool; + SingleSidedInsurancePool proxypool; + CapitalAgent capitalAgent; + TransparentProxy capitalAgentProxy; + TransparentProxy poolProxy; + CapitalAgent proxycapital; + uint public startTime; + uint public nextTime; + uint public nextTime1; + uint public finishTime; + RiskPoolFactory riskPoolFactory; + RewarderFactory rewardFactory; + + address user = address(1); + address user2 = address(2); + + uint256 constant MCR = 10000000; + uint256 constant MLR = 1000000; + uint256 rewardMultiplier = 7000000000000000000; + uint256 poolSCR = 1000000; + uint256 value = 5000000000000000000; + + function setUp() public { + wsys = new WsysMock("Wrapped Sys", "WSYS", 7000000000000000000000); + uno = new MockUNO(); + rewardFactory = new RewarderFactory(); + capitalAgent = new CapitalAgent(); + capitalAgentProxy = new TransparentProxy(address(capitalAgent), address(this), ""); + proxycapital = CapitalAgent(address(capitalAgentProxy)); + proxycapital.initialize(address(this), address(wsys), address(this), address(this)); + proxycapital.setMCR(MCR); + proxycapital.setMLR(MLR); + + riskPoolFactory = new RiskPoolFactory(); + + pool = new SingleSidedInsurancePool(); + poolProxy = new TransparentProxy(address(pool), address(this), ""); + proxypool = SingleSidedInsurancePool(address(poolProxy)); + proxypool.initialize(address(proxycapital), address(this)); + proxycapital.addPoolWhiteList(address(proxypool)); + + proxypool.createRiskPool( + "Synthetic SSIP-WSYS", + "SSSIP-WSYS", + address(riskPoolFactory), + address(wsys), + rewardMultiplier, + poolSCR + ); + proxypool.createRewarder(address(this), address(rewardFactory), address(uno)); + uno.mint(50000000000000000000000000); + address rewarder = proxypool.rewarder(); + + uno.transfer(rewarder, 50000000000000000000000000); + proxypool.setAccUnoPerShare(10,1); + } + + function enterInPool() internal { + wsys.mint(address(user), value); + + vm.prank(address(user)); + wsys.approve(address(proxypool), value); + + vm.prank(address(user)); + proxypool.enterInPool(value); + + wsys.mint(address(user2), (value * 5)); + + vm.prank(address(user2)); + wsys.approve(address(proxypool), (value * 5)); + + vm.prank(address(user2)); + proxypool.enterInPool((value * 5)); + } + + function test_shouldAccumulateRewardsAfterLeaveFromPool() public { + enterInPool(); + + vm.prank(address(user)); + proxypool.leaveFromPoolInPending(value / 2); + vm.roll(block.number + 1); + //Checks rewards right after withdrawing tokens + uint256 rewardsBefore = proxypool.pendingUno(address(user)); + // wait for 10 days and skip 20 blocks + vm.roll(block.number + 20); + skip(10 * 24 * 60 * 60); + // Checks rewards after a couple of days + uint256 rewardsAfter = proxypool.pendingUno(address(user)); + + assertTrue(rewardsAfter > rewardsBefore); + + vm.prank(address(user)); + proxypool.leaveFromPoolInPending(value / 2); + rewardsBefore = proxypool.pendingUno(address(user)); + vm.roll(block.number + 20); + skip(10 * 24 * 60 * 60); + vm.prank(address(user)); + proxypool.userInfo(address(user)); + rewardsAfter = proxypool.pendingUno(address(user)); + + assertEq(rewardsAfter, rewardsBefore); + } + + function test_shouldNotAccumulateRewards() public { + enterInPool(); + + vm.prank(address(user)); + proxypool.leaveFromPoolInPending(value); + uint256 rewardsBefore = proxypool.pendingUno(address(user)); + + // wait for 10 days + vm.roll(block.number + 20); + skip(10 * 24 * 60 * 60); + + uint256 rewardsAfter = proxypool.pendingUno(address(user)); + + assertEq(rewardsAfter, rewardsBefore); + vm.prank(address(user)); + proxypool.leaveFromPending(value); + } +} diff --git a/test/foundry/rollux/NewMCRRollux.t.sol b/test/foundry/rollux/NewMCRRollux.t.sol index 310c7be..d14e710 100644 --- a/test/foundry/rollux/NewMCRRollux.t.sol +++ b/test/foundry/rollux/NewMCRRollux.t.sol @@ -20,16 +20,24 @@ import "../../../src/TransparentProxy.sol"; contract NewMCRRollux is Test { MockUNO uno; - USDCmock usdc; + USDCmock wsys; SupraPriceOracle priceFeed; SingleSidedInsurancePool pool; CapitalAgent capitalAgent; TransparentProxy capitalAgentProxy; + TransparentProxy pool1Proxy; CapitalAgent proxycapital; + CapitalAgent capitalForked; + SingleSidedInsurancePool proxyPool; + SingleSidedInsurancePool pool1; ExchangeAgent exchange; PayoutRequest payout; SalesPolicyFactory salesFactory; SalesPolicy salesPolicy; + uint public startTime; + uint public nextTime; + uint public nextTime1; + uint public finishTime; address user = address(1); address user2 = address(2); @@ -41,10 +49,10 @@ contract NewMCRRollux is Test { address user8 = address(8); address user9 = address(9); address admin = address(this); - address constant USDC = 0x368433CaC2A0B8D76E64681a9835502a1f2A8A30; + address constant WSYS = 0x4200000000000000000000000000000000000006; address constant UNO = 0x570baA32dB74279a50491E88D712C957F4C9E409; address constant PRICE = 0x9A2F48a2F66Ef86A6664Bb6FbC49a7407d6E33B5; - address constant USDCPOOL = 0x2c89687036445089c962F4621B1F03571BBa798e; + address constant WSYSPOOL = 0x3B61743180857c9D898c336b1604f4742887aa74; address constant SALES_FACTORY = 0xD86D9be9143Dc514340C73502f2B77d93d0B11f4; uint256 constant MCR = 10000000; uint256 constant MLR = 1000000; @@ -52,9 +60,14 @@ contract NewMCRRollux is Test { address constant PAYOUT = 0x1024a3a9D000aD3cd6Ac88490F86aD9FEAef7DCA; address constant EXCHANGE_AGENT_ADDRESS = 0x826404CB1924e8b2773250c9d15503E5CDe7eE20; address constant SALES = 0x5B170693E096D8602f970757068859b9A117fA6D; - // address constant MintAddress = 0x3ad22Ae2dE3dCF105E8DaA12acDd15bD47596863; - address constant USDCMillionaire = 0x3F0e40bC7e9cb5f46E906dAEd18651Fb6212Aa8E; - address constant MULTISIG = 0x100c50947580d9158B7C26f79401404208CFbE62; + address constant MintAddress = 0x3ad22Ae2dE3dCF105E8DaA12acDd15bD47596863; + address constant WSYSMillionaire = 0x66ff2f0AC3214758D1e61B16b41e3d5e62CAEcF1; + address constant WSYSMillionaire1 = 0x6E1aD8E91B9b7B677C2a81FA31B6FaAA657424Fb; + address constant UNOOWNER = 0x64A227E362309D1411195850d310E682B13F9B26; + address constant OPERATOR = 0x100c50947580d9158B7C26f79401404208CFbE62; + address constant MULTISIG = 0x15E18e012cb6635b228e0DF0b6FC72627C8b2429; + address constant CAPITAL = 0xB754842C7b0FA838e08fe5C028dB0ecd919f2d30; + function setUp() public { string memory CHAIN_URL = vm.envString("ROLLUXMAIN_URL"); @@ -68,10 +81,10 @@ contract NewMCRRollux is Test { salesFactory = SalesPolicyFactory(SALES_FACTORY); vm.createSelectFork(CHAIN_URL); - pool = SingleSidedInsurancePool(USDCPOOL); + pool = SingleSidedInsurancePool(WSYSPOOL); vm.createSelectFork(CHAIN_URL); - usdc = USDCmock(USDC); + wsys = USDCmock(WSYS); vm.createSelectFork(CHAIN_URL); exchange = ExchangeAgent(payable(EXCHANGE_AGENT_ADDRESS)); @@ -79,14 +92,20 @@ contract NewMCRRollux is Test { vm.createSelectFork(CHAIN_URL); payout = PayoutRequest((PAYOUT)); + vm.createSelectFork(CHAIN_URL); + capitalForked = CapitalAgent((CAPITAL)); + + vm.createSelectFork(CHAIN_URL); + uno = MockUNO((UNO)); + capitalAgent = new CapitalAgent(); capitalAgentProxy = new TransparentProxy(address(capitalAgent), address(this), ""); proxycapital = CapitalAgent(address(capitalAgentProxy)); - proxycapital.initialize(address(exchange), USDC, address(this), address(this)); + proxycapital.initialize(address(exchange), WSYS, address(this), address(this)); proxycapital.setMCR(MCR); proxycapital.setMLR(MLR); proxycapital.setSalesPolicyFactory(SALES_FACTORY); - vm.prank(MULTISIG); + vm.prank(OPERATOR); payout.setCapitalAgent(ICapitalAgent(address(proxycapital))); vm.prank(0x15E18e012cb6635b228e0DF0b6FC72627C8b2429); @@ -94,57 +113,62 @@ contract NewMCRRollux is Test { vm.prank(0x15E18e012cb6635b228e0DF0b6FC72627C8b2429); pool.setCapitalAgent(address(proxycapital)); - proxycapital.addPoolByAdmin(USDCPOOL, USDC, 1000000); + proxycapital.addPoolByAdmin(WSYSPOOL, WSYS, 1000000); + + uint256 fullBalance = wsys.balanceOf(WSYSMillionaire1); + + vm.prank(WSYSMillionaire1); + wsys.transfer(WSYSMillionaire, fullBalance); } function setupUsersAndStakes(uint256 amount, uint256 amount2, uint256 amount3, uint256 amount4) internal { - vm.assume(amount > 0 && amount < 500000000); - vm.assume(amount2 > 0 && amount2 < 500000000); - vm.assume(amount3 > 0 && amount3 < 500000000); - vm.assume(amount4 > 0 && amount4 < 500000000); + vm.assume(amount > 0 && amount < 500000); + vm.assume(amount2 > 0 && amount2 < 500000); + vm.assume(amount3 > 0 && amount3 < 500000); + vm.assume(amount4 > 0 && amount4 < 500000); // Mint - vm.prank(USDCMillionaire); - usdc.transfer(address(user), 500000000); - vm.prank(USDCMillionaire); - usdc.transfer(address(user2), amount); - vm.prank(USDCMillionaire); - usdc.transfer(address(user3), amount2); - vm.prank(USDCMillionaire); - usdc.transfer(address(user4), amount); - vm.prank(USDCMillionaire); - usdc.transfer(address(user5), amount2); - vm.prank(USDCMillionaire); - usdc.transfer(address(user6), amount4); - vm.prank(USDCMillionaire); - usdc.transfer(address(user7), amount); - vm.prank(USDCMillionaire); - usdc.transfer(address(user8), amount3); - vm.prank(USDCMillionaire); - usdc.transfer(address(user9), 10000000); + vm.prank(WSYSMillionaire); + wsys.transfer(address(user), 500000); + vm.prank(WSYSMillionaire); + wsys.transfer(address(user2), amount); + vm.prank(WSYSMillionaire); + wsys.transfer(address(user3), amount2); + vm.prank(WSYSMillionaire); + wsys.transfer(address(user4), amount); + vm.prank(WSYSMillionaire); + wsys.transfer(address(user5), amount2); + vm.prank(WSYSMillionaire); + wsys.transfer(address(user6), amount4); + vm.prank(WSYSMillionaire); + wsys.transfer(address(user7), amount); + vm.prank(WSYSMillionaire); + wsys.transfer(address(user8), amount3); + vm.prank(WSYSMillionaire); + wsys.transfer(address(user9), 10000000); // Approve vm.prank(address(user)); - usdc.approve(address(pool), 500000000); + wsys.approve(address(pool), 500000); vm.prank(address(user2)); - usdc.approve(address(pool), amount); + wsys.approve(address(pool), amount); vm.prank(address(user3)); - usdc.approve(address(pool), amount2); + wsys.approve(address(pool), amount2); vm.prank(address(user4)); - usdc.approve(address(pool), amount); + wsys.approve(address(pool), amount); vm.prank(address(user5)); - usdc.approve(address(pool), amount2); + wsys.approve(address(pool), amount2); vm.prank(address(user6)); - usdc.approve(address(pool), amount4); + wsys.approve(address(pool), amount4); vm.prank(address(user7)); - usdc.approve(address(pool), amount); + wsys.approve(address(pool), amount); vm.prank(address(user8)); - usdc.approve(address(pool), amount3); + wsys.approve(address(pool), amount3); vm.prank(address(user9)); - usdc.approve(address(pool), 10000000); + wsys.approve(address(pool), 10000000); // Enter in pool vm.prank(address(user)); - pool.enterInPool(500000000); + pool.enterInPool(500000); vm.prank(address(user2)); pool.enterInPool(amount); vm.prank(address(user3)); @@ -204,27 +228,27 @@ contract NewMCRRollux is Test { function test_stake(uint256 amount) public { vm.assume(amount < 10000000); vm.assume(0 < amount); - vm.prank(USDCMillionaire); - usdc.transfer(address(user), amount); + vm.prank(WSYSMillionaire); + wsys.transfer(address(user), amount); address riskPool = pool.riskPool(); - uint256 balanceBefore = usdc.balanceOf(riskPool); - assertEq(usdc.balanceOf(user), amount); + uint256 balanceBefore = wsys.balanceOf(riskPool); + assertEq(wsys.balanceOf(user), amount); vm.prank(address(user)); - usdc.approve(address(pool), amount); + wsys.approve(address(pool), amount); vm.prank(address(user)); pool.enterInPool(amount); - assertEq(usdc.balanceOf(address(riskPool)), (balanceBefore + amount)); + assertEq(wsys.balanceOf(address(riskPool)), (balanceBefore + amount)); } function test_stakeWithdrawal(uint256 amount) public { vm.assume(amount < 10000000000); vm.assume(amount > 0); - vm.prank(USDCMillionaire); - usdc.transfer(address(user), 10000000000); - assertEq(usdc.balanceOf(user), 10000000000); + vm.prank(WSYSMillionaire); + wsys.transfer(address(user), 10000000000); + assertEq(wsys.balanceOf(user), 10000000000); vm.prank(address(user)); - usdc.approve(address(pool), 10000000000); + wsys.approve(address(pool), 10000000000); vm.prank(address(user)); pool.enterInPool(10000000000); assertEq(proxycapital.totalCapitalStaked(), 10000000000); @@ -233,15 +257,16 @@ contract NewMCRRollux is Test { skip(900000); vm.prank(address(user)); pool.leaveFromPending(amount); - assertEq(usdc.balanceOf(user), amount); + assertEq(wsys.balanceOf(user), amount); assertEq(proxycapital.totalCapitalStaked(), (10000000000 - amount)); } function test_initialSetupAndStaking(uint256 amount, uint256 amount2, uint256 amount3, uint256 amount4) public { + address riskPool = pool.riskPool(); + uint256 balanceBefore = wsys.balanceOf(riskPool); setupUsersAndStakes(amount, amount2, amount3, amount4); - - uint256 expectedStake = 500000000 + (3 * amount) + (2 * amount2) + amount3 + amount4 + 10000000; - assertEq(proxycapital.totalCapitalStaked(), expectedStake); + uint256 expectedStake = 500000 + (3 * amount) + (2 * amount2) + amount3 + amount4 + 10000000; + assertEq(wsys.balanceOf(riskPool), balanceBefore + expectedStake); } function test_withdrawalProcess(uint256 amount, uint256 amount2, uint256 amount3, uint256 amount4) public { @@ -263,11 +288,7 @@ contract NewMCRRollux is Test { pool.leaveFromPending(amount); vm.prank(address(user)); - vm.expectRevert(); - pool.leaveFromPoolInPending(5000000000); - - vm.prank(address(user)); - pool.leaveFromPoolInPending(50000000); + pool.leaveFromPoolInPending(500000); } function test_cantWithdrawAmountBelowMCR(uint256 amount, uint256 amount2, uint256 amount3, uint256 amount4) public { @@ -277,14 +298,14 @@ contract NewMCRRollux is Test { proxycapital.setMCR(stakedAfter / 2); - vm.prank(USDCMillionaire); - usdc.transfer(address(user), 500000000); + vm.prank(WSYSMillionaire); + wsys.transfer(address(user), 500000); vm.prank(address(user)); - usdc.approve(address(pool), 500000000); + wsys.approve(address(pool), 500000); vm.prank(address(user)); - pool.enterInPool(500000000); + pool.enterInPool(500000); - uint256 totalUserStaked = (2 * 500000000); + uint256 totalUserStaked = (2 * 500000); //Here user will withdrawal all of his money and should not fail by the MCR vm.prank(address(user)); @@ -295,7 +316,7 @@ contract NewMCRRollux is Test { //here user stake all his money again vm.prank(address(user)); - usdc.approve(address(pool), totalUserStaked); + wsys.approve(address(pool), totalUserStaked); vm.prank(address(user)); pool.enterInPool(totalUserStaked); @@ -313,39 +334,4 @@ contract NewMCRRollux is Test { vm.expectRevert(); pool.leaveFromPoolInPending(totalUserStaked); } - - function test_shouldNotFailWithdrawalCompletion(uint256 amount, uint256 amount2, uint256 amount3, uint256 amount4) public { - setupUsersAndStakes(amount, amount2, amount3, amount4); - - uint256 stakedAfter = proxycapital.totalCapitalStaked(); - - proxycapital.setMCR(stakedAfter / 2); - - vm.prank(USDCMillionaire); - usdc.transfer(address(user), 500000000); - vm.prank(address(user)); - usdc.approve(address(pool), 500000000); - vm.prank(address(user)); - pool.enterInPool(500000000); - - uint256 totalUserStaked = (2 * 500000000); - - proxycapital.totalCapitalStaked(); - proxycapital.MCR(); - - //Here other users will start to withdrawal all of their money, but won't finish withdrawing yet - - setupStartWithdrawal(amount, amount2, amount3, amount4); - skip(900000); - - vm.prank(address(user)); - //this call should fail by the MCR as other users withdrew, but it doesn't - pool.leaveFromPoolInPending(totalUserStaked); - skip(900000); - - vm.prank(address(user)); - pool.leaveFromPending(totalUserStaked); - - setupFinishWithdrawal(amount, amount2, amount3, amount4); - } }