Skip to content

Commit

Permalink
Lint and add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dulguun-staderlabs committed Jan 14, 2024
1 parent 45358bb commit 6d75aa2
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 24 deletions.
11 changes: 7 additions & 4 deletions contracts/OperatorRewardsCollector.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ contract OperatorRewardsCollector is IOperatorRewardsCollector, AccessControlUpg
*/
function claim() external {
uint256 amount = balances[msg.sender] > withdrawableInEth(msg.sender)
? withdrawableInEth(msg.sender)
: balances[msg.sender];
? withdrawableInEth(msg.sender)
: balances[msg.sender];

claimLiquidation(msg.sender);
_transferBackUtilizedSD(msg.sender);
Expand All @@ -70,13 +70,16 @@ contract OperatorRewardsCollector is IOperatorRewardsCollector, AccessControlUpg
uint256 liquidationThreshold = sdUtilityPool.getLiquidationThreshold();
UserData memory userData = sdUtilityPool.getUserData(operator);
uint256 totalInterestAdjusted = (userData.totalInterestSD * 100) / liquidationThreshold;

if (totalInterestAdjusted > userData.totalCollateralInSD) return 0;
uint256 withdrawableInSd = userData.totalCollateralInSD - totalInterestAdjusted;

OperatorLiquidation memory operatorLiquidation = sdUtilityPool.getOperatorLiquidation(operator);
uint256 availableBalance = ISDCollateral(staderConfig.getSDCollateral()).convertSDToETH(withdrawableInSd);
return availableBalance > operatorLiquidation.totalAmountInEth? availableBalance - operatorLiquidation.totalAmountInEth : 0;
return
availableBalance > operatorLiquidation.totalAmountInEth
? availableBalance - operatorLiquidation.totalAmountInEth
: 0;
}

function updateWethAddress(address _weth) external onlyRole(DEFAULT_ADMIN_ROLE) {
Expand Down
2 changes: 1 addition & 1 deletion contracts/interfaces/IOperatorRewardsCollector.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ interface IOperatorRewardsCollector {
function depositFor(address _receiver) external payable;

function claim() external;

function claimLiquidation(address operator) external;

function withdrawableInEth(address operator) external view returns (uint256);
Expand Down
5 changes: 1 addition & 4 deletions scripts/deploy/sdIncentiveController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ async function main() {
const staderConfigAddr = process.env.STADER_CONFIG ?? ''

const sdIncentiveControllerFactory = await ethers.getContractFactory('SDIncentiveController')
const sdIncentiveController = await upgrades.deployProxy(sdIncentiveControllerFactory, [
owner,
staderConfigAddr,
])
const sdIncentiveController = await upgrades.deployProxy(sdIncentiveControllerFactory, [owner, staderConfigAddr])
console.log('SD Incentive Controller deployed to: ', sdIncentiveController.address)
}

Expand Down
5 changes: 1 addition & 4 deletions scripts/deploy/sdUtilityPool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ async function main() {
const staderConfigAddr = process.env.STADER_CONFIG ?? ''

const sdUtilityPoolFactory = await ethers.getContractFactory('SDUtilityPool')
const sdUtilityPool = await upgrades.deployProxy(sdUtilityPoolFactory, [
owner,
staderConfigAddr,
])
const sdUtilityPool = await upgrades.deployProxy(sdUtilityPoolFactory, [owner, staderConfigAddr])
console.log('Utility pool deployed to: ', sdUtilityPool.address)
}

Expand Down
132 changes: 129 additions & 3 deletions test/foundry_tests/SDIncentiveController.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,11 @@ contract SDIncentiveControllerTest is Test {

vm.roll(block.number + 10);

assertApproxEqAbs(sdIncentiveController.earned(address(this)) + sdIncentiveController.earned(user2), (incentiveAmount / duration) * 10, 1e9);
assertApproxEqAbs(
sdIncentiveController.earned(address(this)) + sdIncentiveController.earned(user2),
(incentiveAmount / duration) * 10,
1e9
);

vm.startPrank(user);
staderToken.approve(address(sdUtilityPool), sdAmount);
Expand All @@ -194,11 +198,20 @@ contract SDIncentiveControllerTest is Test {
vm.stopPrank();

vm.roll(block.number + duration);
uint256 preEarned = earned + sdIncentiveController.earned(user2) + sdIncentiveController.earned(user) + sdIncentiveController.earned(address(this));
uint256 preEarned = earned +
sdIncentiveController.earned(user2) +
sdIncentiveController.earned(user) +
sdIncentiveController.earned(address(this));
assertApproxEqAbs(preEarned, incentiveAmount, 1e9);

vm.roll(block.number + duration * 10);
assertEq(earned + sdIncentiveController.earned(user2) + sdIncentiveController.earned(user) + sdIncentiveController.earned(address(this)), preEarned);
assertEq(
earned +
sdIncentiveController.earned(user2) +
sdIncentiveController.earned(user) +
sdIncentiveController.earned(address(this)),
preEarned
);
}

function test_NoIncentive(uint128 sdAmount, uint16 randomSeed) public {
Expand Down Expand Up @@ -255,6 +268,68 @@ contract SDIncentiveControllerTest is Test {
assertEq(earned + sdIncentiveController.earned(user2) + sdIncentiveController.earned(user), preEarned);
}

function testWithdrawMultiples(
uint256 utilizeAmount,
uint256 incentiveAmount,
uint256 duration
) public {
vm.assume(utilizeAmount > 1e20 && utilizeAmount < 1e25);

address user1 = address(1);
address user2 = address(2);

(incentiveAmount, duration) = setupIncentive(incentiveAmount, duration);

staderToken.transfer(user1, utilizeAmount);
staderToken.transfer(user2, utilizeAmount);

vm.startPrank(user1);
staderToken.approve(address(sdUtilityPool), utilizeAmount / 10);
sdUtilityPool.delegate(utilizeAmount / 10);
vm.stopPrank();

vm.startPrank(user2);
staderToken.approve(address(sdUtilityPool), utilizeAmount);
sdUtilityPool.delegate(utilizeAmount);
vm.stopPrank();

vm.roll(block.number + duration);
uint256 earn1 = sdIncentiveController.earned(user1);
uint256 earn2 = sdIncentiveController.earned(user2);

uint256 user1PrevBalance = staderToken.balanceOf(user1);
uint256 user2PrevBalance = staderToken.balanceOf(user2);

vm.startPrank(user1);
sdUtilityPool.requestWithdrawWithSDAmount(utilizeAmount / 10);
vm.stopPrank();

vm.startPrank(user2);
sdUtilityPool.requestWithdrawWithSDAmount(utilizeAmount);
vm.stopPrank();

vm.startPrank(staderAdmin);
sdUtilityPool.updateMinBlockDelayToFinalizeRequest(0);
sdUtilityPool.finalizeDelegatorWithdrawalRequest();
vm.stopPrank();

vm.startPrank(user1);
sdUtilityPool.claim(1);
vm.stopPrank();

vm.startPrank(user2);
sdUtilityPool.claim(2);
vm.stopPrank();

assertTrue(earn1 > 0, 'User1 did not earn any rewards');
assertTrue(earn2 > 0, 'User2 did not earn any rewards');

uint256 user1FinalGain = staderToken.balanceOf(user1) - user1PrevBalance;
uint256 user2FinalGain = staderToken.balanceOf(user2) - user2PrevBalance;

assertApproxEqAbs(user2FinalGain / 10, user1FinalGain, 10);
}

function test_UpdateStaderConfig(uint16 randomSeed) public {
vm.assume(randomSeed > 0);
address inputAddr = vm.addr(randomSeed);
Expand All @@ -266,4 +341,55 @@ contract SDIncentiveControllerTest is Test {
sdIncentiveController.updateStaderConfig(inputAddr);
assertEq(address(sdIncentiveController.staderConfig()), inputAddr);
}

function test_startIncentive(uint256 incentiveAmount, uint256 duration) public {
vm.assume(incentiveAmount > 0);
vm.assume(duration > 0);

incentiveAmount = ((incentiveAmount % 10000) + 2) * 1e18;
duration = ((duration % 10) + 1) * 100;
incentiveAmount = (incentiveAmount / duration) * duration;
staderToken.transfer(staderManager, incentiveAmount);

staderToken.approve(address(sdIncentiveController), incentiveAmount);
vm.expectRevert(UtilLib.CallerNotManager.selector);
sdIncentiveController.start(incentiveAmount, duration);

// 0 rewards
vm.startPrank(staderManager);
vm.expectRevert(ISDIncentiveController.InvalidRewardAmount.selector);
sdIncentiveController.start(0, duration);
vm.stopPrank();

// 0 duration
vm.startPrank(staderManager);
staderToken.approve(address(sdIncentiveController), incentiveAmount);
vm.expectRevert(ISDIncentiveController.InvalidEndBlock.selector);
sdIncentiveController.start(incentiveAmount, 0);
vm.stopPrank();

// Undivisible reward and duration
vm.startPrank(staderManager);
staderToken.approve(address(sdIncentiveController), 123456);
vm.expectRevert(ISDIncentiveController.InvalidRewardAmount.selector);
sdIncentiveController.start(123456, 10);
vm.stopPrank();

// No approval
vm.startPrank(staderManager);
vm.expectRevert('ERC20: insufficient allowance');
sdIncentiveController.start(1e22, 10);
vm.stopPrank();

// Less than DECIMAL
vm.startPrank(staderManager);
vm.expectRevert(ISDIncentiveController.InvalidRewardAmount.selector);
sdIncentiveController.start(1e17, 10);
vm.stopPrank();

vm.startPrank(staderManager);
staderToken.approve(address(sdIncentiveController), incentiveAmount);
sdIncentiveController.start(incentiveAmount, duration);
vm.stopPrank();
}
}
4 changes: 2 additions & 2 deletions test/foundry_tests/SDUtilityPool.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -735,7 +735,7 @@ contract SDUtilityPoolTest is Test {

vm.roll(block.number + 10000000);
UserData memory userData = sdUtilityPool.getUserData(operator);

vm.startPrank(liquidator);
assertGt(userData.healthFactor, 1e18);
vm.expectRevert(ISDUtilityPool.NotLiquidatable.selector);
Expand All @@ -746,7 +746,7 @@ contract SDUtilityPoolTest is Test {

uint256 beforeBalance = staderToken.balanceOf(liquidator);
userData = sdUtilityPool.getUserData(operator);

assertLt(userData.healthFactor, 1e18);
vm.startPrank(staderManager);
sdUtilityPool.pause();
Expand Down
8 changes: 2 additions & 6 deletions test/mocks/WethMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,9 @@
pragma solidity 0.8.16;

contract WETHMock {
function deposit() external payable {
function deposit() external payable {}

}

function withdraw(uint256) external {

}
function withdraw(uint256) external {}

function transferFrom(
address src,
Expand Down

0 comments on commit 6d75aa2

Please sign in to comment.