Skip to content

Commit

Permalink
all tests passing
Browse files Browse the repository at this point in the history
  • Loading branch information
0xean committed Apr 24, 2024
1 parent 64994d1 commit 1ffafa9
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 63 deletions.
37 changes: 23 additions & 14 deletions foundry/src/FoxStakingV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ contract FoxStakingV1 is
uint256 amount,
string indexed runeAddress
);
event Unstake(address indexed account, uint256 amount, uint256 cooldownExpiry);
event Unstake(
address indexed account,
uint256 amount,
uint256 cooldownExpiry
);
event Withdraw(address indexed account, uint256 amount);
event SetRuneAddress(
address indexed account,
Expand Down Expand Up @@ -173,35 +177,32 @@ contract FoxStakingV1 is
emit Unstake(msg.sender, amount, unstakingInfo.cooldownExpiry);
}


// this function seems odd at first, but we have to take into account the possibility
// that the cool down period has changed, and its possible the array is NOT in chronological
// order of expiration. If that occurs, a user could want to be able to process index 1 before
// index 0. This gives them the ability to do that, without have to worry about
// some complex resize logic while we iterate the array that would better be done off chain
function withdraw(uint256 index) public whenNotPaused whenWithdrawalsNotPaused {
function withdraw(
uint256 index
) public whenNotPaused whenWithdrawalsNotPaused {
StakingInfo storage info = stakingInfo[msg.sender];
require (
info.unstakingInfo.length > 0,
"No balance to unstake"
);
require(info.unstakingInfo.length > 0, "No balance to withdraw");

require (
info.unstakingInfo.length > index,
"invalid index"
);
require(info.unstakingInfo.length > index, "invalid index");

UnstakingInfo memory unstakingInfo = info.unstakingInfo[index];

require(
block.timestamp >= unstakingInfo.cooldownExpiry,
"Unstake cooldown period has not expired"
"Not cooled down yet"
);

if (info.unstakingInfo.length > 1) {
// we have more elements in the array, so shift the last element to the index being withdrawn
// and then shorten the array by 1
info.unstakingInfo[index] = info.unstakingInfo[info.unstakingInfo.length - 1];
info.unstakingInfo[index] = info.unstakingInfo[
info.unstakingInfo.length - 1
];
info.unstakingInfo.pop();
} else {
// the array is done, we can delete the whole thing
Expand Down Expand Up @@ -240,4 +241,12 @@ contract FoxStakingV1 is
StakingInfo memory info = stakingInfo[account];
return info.stakingBalance + info.unstakingBalance;
}

function getUnstakingInfo(address account, uint256 index)
external
view
returns (UnstakingInfo memory)
{
return stakingInfo[account].unstakingInfo[index];
}
}
2 changes: 1 addition & 1 deletion foundry/src/StakingInfo.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ import {UnstakingInfo} from "./UnstakingInfo.sol";
struct StakingInfo {
uint256 stakingBalance;
uint256 unstakingBalance;
UnstakingInfo[] unstakingInfo;
string runeAddress;
UnstakingInfo[] unstakingInfo;
}
2 changes: 1 addition & 1 deletion foundry/test/FOXStakingTestRuneAddress.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ contract FOXStakingTestRuneAddress is Test {

foxStaking.setRuneAddress(newRuneAddress);

(, , , string memory runeAddress) = foxStaking.stakingInfo(user);
(, , string memory runeAddress) = foxStaking.stakingInfo(user);
assertEq(
runeAddress,
newRuneAddress,
Expand Down
17 changes: 3 additions & 14 deletions foundry/test/FOXStakingTestStaking.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ contract FOXStakingTestStaking is Test {
(
uint256 stakingBalance_before,
uint256 unstakingBalance_before,
,

) = foxStaking.stakingInfo(user);
vm.assertEq(stakingBalance_before + unstakingBalance_before, 0);
Expand All @@ -69,8 +68,6 @@ contract FOXStakingTestStaking is Test {
(
uint256 stakingBalance_after,
uint256 unstakingBalance_after,
,

) = foxStaking.stakingInfo(user);
vm.assertEq(stakingBalance_after + unstakingBalance_after, 1000);
vm.assertEq(stakingBalance_after, 1000);
Expand Down Expand Up @@ -102,8 +99,6 @@ contract FOXStakingTestStaking is Test {
(
uint256 stakingBalance_before,
uint256 unstakingBalance_before,
,

) = foxStaking.stakingInfo(user);
vm.assertEq(stakingBalance_before + unstakingBalance_before, 0);
vm.assertEq(stakingBalance_before, 0);
Expand All @@ -127,8 +122,6 @@ contract FOXStakingTestStaking is Test {
(
uint256 stakingBalance_after,
uint256 unstakingBalance_after,
,

) = foxStaking.stakingInfo(user);
vm.assertEq(stakingBalance_after + unstakingBalance_after, 1000);
vm.assertEq(stakingBalance_after, 1000);
Expand All @@ -143,7 +136,7 @@ contract FOXStakingTestStaking is Test {
vm.startPrank(user);

// Check user staking balances
(uint256 stakingBalance, uint256 unstakingBalance, , ) = foxStaking
(uint256 stakingBalance, uint256 unstakingBalance, ) = foxStaking
.stakingInfo(user);
vm.assertEq(stakingBalance + unstakingBalance, 0);
vm.assertEq(stakingBalance, 0);
Expand All @@ -157,8 +150,6 @@ contract FOXStakingTestStaking is Test {
(
uint256 stakingBalance_after,
uint256 unstakingBalance_after,
,

) = foxStaking.stakingInfo(user);
vm.assertEq(stakingBalance_after + unstakingBalance_after, 0);
vm.assertEq(stakingBalance_after, 0);
Expand All @@ -173,7 +164,7 @@ contract FOXStakingTestStaking is Test {
vm.startPrank(user);

// Check user staking balances
(uint256 stakingBalance, uint256 unstakingBalance, , ) = foxStaking
(uint256 stakingBalance, uint256 unstakingBalance, ) = foxStaking
.stakingInfo(user);
vm.assertEq(stakingBalance + unstakingBalance, 0);
vm.assertEq(stakingBalance, 0);
Expand All @@ -187,8 +178,6 @@ contract FOXStakingTestStaking is Test {
(
uint256 stakingBalance_after,
uint256 unstakingBalance_after,
,

) = foxStaking.stakingInfo(user);
vm.assertEq(stakingBalance_after + unstakingBalance_after, 0);
vm.assertEq(stakingBalance_after, 0);
Expand Down Expand Up @@ -231,7 +220,7 @@ contract FOXStakingTestStaking is Test {
assertEq(total, amounts[i]);

// Verify each user's rune address
(, , , string memory runeAddress) = foxStaking.stakingInfo(
(, , string memory runeAddress) = foxStaking.stakingInfo(
users[i]
);
assertEq(runeAddress, runeAddresses[i]);
Expand Down
30 changes: 3 additions & 27 deletions foundry/test/FOXStakingTestUnstake.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ contract FOXStakingTestUnstake is Test {
(
uint256 stakingBalance_before,
uint256 unstakingBalance_before,
,

) = foxStaking.stakingInfo(user);
vm.assertEq(stakingBalance_before + unstakingBalance_before, 1000);
vm.assertEq(stakingBalance_before, 1000);
Expand All @@ -76,8 +74,6 @@ contract FOXStakingTestUnstake is Test {
(
uint256 stakingBalance_after,
uint256 unstakingBalance_after,
,

) = foxStaking.stakingInfo(user);
vm.assertEq(stakingBalance_after + unstakingBalance_after, 1000);
vm.assertEq(stakingBalance_after, 0);
Expand All @@ -101,7 +97,7 @@ contract FOXStakingTestUnstake is Test {
vm.startPrank(user);

// Check user staking balances
(uint256 stakingBalance, uint256 unstakingBalance, , ) = foxStaking
(uint256 stakingBalance, uint256 unstakingBalance, ) = foxStaking
.stakingInfo(user);
vm.assertEq(stakingBalance + unstakingBalance, 1000);
vm.assertEq(stakingBalance, 1000);
Expand All @@ -115,8 +111,6 @@ contract FOXStakingTestUnstake is Test {
(
uint256 stakingBalance_after,
uint256 unstakingBalance_after,
,

) = foxStaking.stakingInfo(user);

vm.assertEq(stakingBalance_after + unstakingBalance_after, 1000);
Expand All @@ -133,8 +127,6 @@ contract FOXStakingTestUnstake is Test {
(
uint256 stakingBalance_before,
uint256 unstakingBalance_before,
,

) = foxStaking.stakingInfo(user);
vm.assertEq(stakingBalance_before + unstakingBalance_before, 1000);
vm.assertEq(stakingBalance_before, 1000);
Expand All @@ -148,8 +140,6 @@ contract FOXStakingTestUnstake is Test {
(
uint256 stakingBalance_after,
uint256 unstakingBalance_after,
,

) = foxStaking.stakingInfo(user);
vm.assertEq(stakingBalance_after + unstakingBalance_after, 1000);
vm.assertEq(stakingBalance_after, 1000);
Expand All @@ -165,8 +155,6 @@ contract FOXStakingTestUnstake is Test {
(
uint256 stakingBalance_before,
uint256 unstakingBalance_before,
,

) = foxStaking.stakingInfo(user);
vm.assertEq(stakingBalance_before + unstakingBalance_before, 1000);
vm.assertEq(stakingBalance_before, 1000);
Expand All @@ -179,8 +167,6 @@ contract FOXStakingTestUnstake is Test {
(
uint256 stakingBalance_after,
uint256 unstakingBalance_after,
,

) = foxStaking.stakingInfo(user);
vm.assertEq(stakingBalance_after + unstakingBalance_after, 1000);
vm.assertEq(stakingBalance_after, 0);
Expand All @@ -196,8 +182,6 @@ contract FOXStakingTestUnstake is Test {
(
uint256 stakingBalance_before,
uint256 unstakingBalance_before,
,

) = foxStaking.stakingInfo(user);
vm.assertEq(stakingBalance_before + unstakingBalance_before, 1000);
vm.assertEq(stakingBalance_before, 1000);
Expand All @@ -210,8 +194,6 @@ contract FOXStakingTestUnstake is Test {
(
uint256 stakingBalance_after,
uint256 unstakingBalance_after,
,

) = foxStaking.stakingInfo(user);
vm.assertEq(stakingBalance_after + unstakingBalance_after, 1000);
vm.assertEq(stakingBalance_after, 200);
Expand All @@ -228,8 +210,6 @@ contract FOXStakingTestUnstake is Test {
(
uint256 stakingBalance_before,
uint256 unstakingBalance_before,
,

) = foxStaking.stakingInfo(user);
vm.assertEq(stakingBalance_before + unstakingBalance_before, 1000);
vm.assertEq(stakingBalance_before, 1000);
Expand All @@ -246,9 +226,8 @@ contract FOXStakingTestUnstake is Test {
(
uint256 stakingBalance_one,
uint256 unstakingBalance_one,
uint256 cooldownExpiry_one,

) = foxStaking.stakingInfo(user);
uint256 cooldownExpiry_one = foxStaking.getUnstakingInfo(user, 0).cooldownExpiry;
vm.assertEq(cooldownExpiry_one, block.timestamp + 28 days);

// Check user staking balances reflect the withdrawal request
Expand All @@ -266,8 +245,6 @@ contract FOXStakingTestUnstake is Test {
(
uint256 stakingBalance_two,
uint256 unstakingBalance_two,
,

) = foxStaking.stakingInfo(user);
vm.assertEq(stakingBalance_two + unstakingBalance_two, 700);
vm.assertEq(stakingBalance_two, 700);
Expand All @@ -280,9 +257,8 @@ contract FOXStakingTestUnstake is Test {
(
uint256 stakingBalance_three,
uint256 unstakingBalance_three,
uint256 cooldownExpiry_three,

) = foxStaking.stakingInfo(user);
uint256 cooldownExpiry_three = foxStaking.getUnstakingInfo(user, 0).cooldownExpiry;
vm.assertGt(cooldownExpiry_three, block.timestamp);

// Check user staking balances reflect the withdrawal request
Expand Down
6 changes: 1 addition & 5 deletions foundry/test/FOXStakingTestWithdraw.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ contract FOXStakingTestWithdraw is Test {
(
uint256 stakingBalance_before,
uint256 unstakingBalance_before,
,

) = foxStaking.stakingInfo(user);
vm.assertEq(stakingBalance_before + unstakingBalance_before, 1000);
vm.assertEq(stakingBalance_before, 1000);
Expand Down Expand Up @@ -94,8 +92,6 @@ contract FOXStakingTestWithdraw is Test {
(
uint256 stakingBalance_after,
uint256 unstakingBalance_after,
,

) = foxStaking.stakingInfo(user);
vm.assertEq(stakingBalance_after + unstakingBalance_after, 0);
vm.assertEq(stakingBalance_after, 0);
Expand Down Expand Up @@ -160,7 +156,7 @@ contract FOXStakingTestWithdraw is Test {
vm.warp(block.timestamp + 28 days);

// Try to withdraw 0
vm.expectRevert("Cannot withdraw 0");
vm.expectRevert("No balance to withdraw");
foxStaking.withdraw();

// Check user wallet balance of FOX is still 0
Expand Down
38 changes: 37 additions & 1 deletion scripts/rewards-distribution/generated/abi-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,30 @@ export const foxStakingV1Abi = [
outputs: [{ name: "", internalType: "contract IERC20", type: "address" }],
stateMutability: "view",
},
{
type: "function",
inputs: [
{ name: "account", internalType: "address", type: "address" },
{ name: "index", internalType: "uint256", type: "uint256" },
],
name: "getUnstakingInfo",
outputs: [
{
name: "",
internalType: "struct UnstakingInfo",
type: "tuple",
components: [
{
name: "unstakingBalance",
internalType: "uint256",
type: "uint256",
},
{ name: "cooldownExpiry", internalType: "uint256", type: "uint256" },
],
},
],
stateMutability: "view",
},
{
type: "function",
inputs: [
Expand Down Expand Up @@ -130,7 +154,6 @@ export const foxStakingV1Abi = [
outputs: [
{ name: "stakingBalance", internalType: "uint256", type: "uint256" },
{ name: "unstakingBalance", internalType: "uint256", type: "uint256" },
{ name: "cooldownExpiry", internalType: "uint256", type: "uint256" },
{ name: "runeAddress", internalType: "string", type: "string" },
],
stateMutability: "view",
Expand Down Expand Up @@ -208,6 +231,13 @@ export const foxStakingV1Abi = [
outputs: [{ name: "", internalType: "uint256", type: "uint256" }],
stateMutability: "view",
},
{
type: "function",
inputs: [{ name: "index", internalType: "uint256", type: "uint256" }],
name: "withdraw",
outputs: [],
stateMutability: "nonpayable",
},
{
type: "function",
inputs: [],
Expand Down Expand Up @@ -346,6 +376,12 @@ export const foxStakingV1Abi = [
type: "uint256",
indexed: false,
},
{
name: "cooldownExpiry",
internalType: "uint256",
type: "uint256",
indexed: false,
},
],
name: "Unstake",
},
Expand Down

0 comments on commit 1ffafa9

Please sign in to comment.