From 0ec8d8b38d69c8a18c18df78a0e91f892df3a7d5 Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Tue, 9 Apr 2024 20:17:13 +0200 Subject: [PATCH] feat: all green --- foundry/src/FoxStaking.sol | 10 +++--- foundry/test/FoxStaking.t.sol | 61 +++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/foundry/src/FoxStaking.sol b/foundry/src/FoxStaking.sol index f1cb086..e5a4251 100644 --- a/foundry/src/FoxStaking.sol +++ b/foundry/src/FoxStaking.sol @@ -5,12 +5,14 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {Pausable} from "@openzeppelin/contracts/utils/Pausable.sol"; import {IFoxStaking, StakingInfo} from "./IFoxStaking.sol"; +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; contract FoxStaking is IFoxStaking, Ownable(msg.sender), // Deployer is the owner Pausable { + using SafeERC20 for IERC20; IERC20 public foxToken; mapping(address => StakingInfo) public stakingInfo; @@ -86,11 +88,7 @@ contract FoxStaking is function stake(uint256 amount, string memory runeAddress) external whenNotPaused whenStakingUnpaused { require(bytes(runeAddress).length > 0, "Rune address cannot be empty"); require(amount > 0, "FOX amount to stake must be greater than 0"); - // Transfer fundus from msg.sender to contract assuming allowance has been set - here goes nothing - require( - foxToken.transferFrom(msg.sender, address(this), amount), - "Transfer failed" - ); + foxToken.safeTransferFrom(msg.sender, address(this), amount); StakingInfo storage info = stakingInfo[msg.sender]; info.stakingBalance += amount; @@ -128,7 +126,7 @@ contract FoxStaking is ); uint256 withdrawAmount = info.unstakingBalance; info.unstakingBalance = 0; - require(foxToken.transfer(msg.sender, withdrawAmount), "Transfer failed"); + foxToken.safeTransfer(msg.sender, withdrawAmount); emit Withdraw(msg.sender, withdrawAmount); } diff --git a/foundry/test/FoxStaking.t.sol b/foundry/test/FoxStaking.t.sol index a67e9a9..be610ca 100644 --- a/foundry/test/FoxStaking.t.sol +++ b/foundry/test/FoxStaking.t.sol @@ -41,6 +41,17 @@ contract FOXStakingTestRuneAddress is Test { vm.stopPrank(); } + + function cannotStakeWithEmptyRuneAddress() public { + vm.startPrank(user); + + string memory emptyRuneAddress = ""; + + vm.expectRevert("Rune address cannot be empty"); + foxStaking.stake(1e18, emptyRuneAddress); + + vm.stopPrank(); + } } contract FOXStakingTestOwnership is Test { @@ -171,6 +182,56 @@ contract FOXStakingTestStaking is Test { vm.assertEq(unstakingBalance_after, 0); } + function testStake_cannotStakeZero() public { + address user = address(0xD00D); + string memory runeAddress = "runeAddress"; + + vm.startPrank(user); + + // Check user staking balances + (uint256 stakingBalance, uint256 unstakingBalance, , ) = foxStaking.stakingInfo(user); + vm.assertEq(stakingBalance + unstakingBalance, 0); + vm.assertEq(stakingBalance, 0); + vm.assertEq(unstakingBalance, 0); + + // Try to stake 0 + vm.expectRevert("FOX amount to stake must be greater than 0"); + foxStaking.stake(0, runeAddress); + + // Check user staking balances are unchanged + (uint256 stakingBalance_after, uint256 unstakingBalance_after, , ) = foxStaking.stakingInfo(user); + vm.assertEq(stakingBalance_after + unstakingBalance_after, 0); + vm.assertEq(stakingBalance_after, 0); + vm.assertEq(unstakingBalance_after, 0); + + vm.stopPrank(); + } + + function testStake_cannotStakeWithEmptyRuneAddress() public { + address user = address(0xD00D); + + vm.startPrank(user); + + // Check user staking balances + (uint256 stakingBalance, uint256 unstakingBalance, , ) = foxStaking.stakingInfo(user); + vm.assertEq(stakingBalance + unstakingBalance, 0); + vm.assertEq(stakingBalance, 0); + vm.assertEq(unstakingBalance, 0); + + // Try to stake with empty rune address + vm.expectRevert("Rune address cannot be empty"); + foxStaking.stake(1e18, ""); + + // Check user staking balances are unchanged + (uint256 stakingBalance_after, uint256 unstakingBalance_after, , ) = foxStaking.stakingInfo(user); + vm.assertEq(stakingBalance_after + unstakingBalance_after, 0); + vm.assertEq(stakingBalance_after, 0); + vm.assertEq(unstakingBalance_after, 0); + + vm.stopPrank(); + } + + // "e2e" staking test for multiple users function testStaking() public { address[] memory users = new address[](3); users[0] = address(0xBABE);