Skip to content

Commit

Permalink
feat: add basic test struct
Browse files Browse the repository at this point in the history
  • Loading branch information
noyyyy committed Dec 1, 2023
1 parent 2911fa2 commit 3826260
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 3 deletions.
1 change: 1 addition & 0 deletions packages/dev/remappings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ foundry-upgrades/=lib/foundry-upgrades/src/
base64-sol=node_modules/base64-sol/
contracts/=contracts/
src/=src/
test/=test/
6 changes: 3 additions & 3 deletions packages/dev/src/bridge/GalaxeBadgeReceiverV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ contract GalaxeBadgeReceiverV2 is IBadgeReceiverV2, Ownable, IERC721Receiver {
mapping(uint256 => uint256) public usdRefund;
mapping(uint256 => uint256) public plRefund;

address public immutable USDToken;
address public immutable usdToken;

constructor(address owner_, address usdToken_) {
_setOwner(owner_);
USDToken = usdToken_;
usdToken = usdToken_;
}

function burnNFT(address nftAddr, uint256 tokenId) external {
Expand Down Expand Up @@ -100,7 +100,7 @@ contract GalaxeBadgeReceiverV2 is IBadgeReceiverV2, Ownable, IERC721Receiver {
uint256 refundAmount = usdRefund[cid];

// refund
IERC20(msg.sender).safeTransfer(msg.sender, refundAmount);
IERC20(usdToken).safeTransfer(msg.sender, refundAmount);

emit BurnAndRefund(nftAddr, cid, tokenId, refundAmount, plRefund[cid]);
}
Expand Down
33 changes: 33 additions & 0 deletions packages/dev/test/Base.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.19 <0.9.0;

import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {ERC20MissingReturn} from "test/mocks/ERC20/ERC20MissingReturn.sol";
import {Test} from "forge-std/Test.sol";

struct Users {
// Default admin for all Sablier V2 contracts.
address payable admin;
// Impartial user.
address payable alice;
// signer
address payable signer;
}

/// @notice Base test contract with common logic needed by all tests.
abstract contract BaseTest is Test {
Users internal users;
ERC20MissingReturn internal usdt;

function setUp() public virtual {
users = Users({admin: createUser("admin"), alice: createUser("alice"), signer: createUser("signer")});
usdt = new ERC20MissingReturn("Tether USD", "USDT", 6);
}

/// @dev Generates a user, labels its address, and funds it with test assets.
function createUser(string memory name) internal returns (address payable) {
address payable user = payable(makeAddr(name));
vm.deal({account: user, newBalance: 100 ether});
return user;
}
}
71 changes: 71 additions & 0 deletions packages/dev/test/mocks/ERC20/ERC20MissingReturn.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.8.19;

/// @notice An implementation of ERC-20 that does not return a boolean in {transfer} and {transferFrom}.
/// @dev See https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca/.
contract ERC20MissingReturn {
uint8 public decimals;
string public name;
string public symbol;
uint256 public totalSupply;

mapping(address owner => mapping(address spender => uint256 allowance)) internal _allowances;
mapping(address account => uint256 balance) internal _balances;

event Transfer(address indexed from, address indexed to, uint256 amount);

event Approval(address indexed owner, address indexed spender, uint256 amount);

constructor(string memory name_, string memory symbol_, uint8 decimals_) {
name = name_;
symbol = symbol_;
decimals = decimals_;
}

function allowance(address owner, address spender) public view returns (uint256) {
return _allowances[owner][spender];
}

function balanceOf(address account) public view returns (uint256) {
return _balances[account];
}

function approve(address spender, uint256 value) public returns (bool) {
_approve(msg.sender, spender, value);
return true;
}

function burn(address holder, uint256 amount) public {
_balances[holder] -= amount;
totalSupply -= amount;
emit Transfer(holder, address(0), amount);
}

function mint(address beneficiary, uint256 amount) public {
_balances[beneficiary] += amount;
totalSupply += amount;
emit Transfer(address(0), beneficiary, amount);
}

function _approve(address owner, address spender, uint256 value) internal virtual {
_allowances[owner][spender] = value;
emit Approval(owner, spender, value);
}

/// @dev This function does not return a value, although the ERC-20 standard mandates that it should.
function transfer(address to, uint256 amount) public {
_transfer(msg.sender, to, amount);
}

/// @dev This function does not return a value, although the ERC-20 standard mandates that it should.
function transferFrom(address from, address to, uint256 amount) public {
_transfer(from, to, amount);
_approve(from, msg.sender, _allowances[from][msg.sender] - amount);
}

function _transfer(address from, address to, uint256 amount) internal virtual {
_balances[from] = _balances[from] - amount;
_balances[to] = _balances[to] + amount;
emit Transfer(from, to, amount);
}
}
29 changes: 29 additions & 0 deletions packages/dev/test/uint/fuzz/GBROnlyOwnerTest.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

import {GalxeBadgeReceiverV2Test} from "test/uint/shared/GalxeBadgeReceiverV2.t.sol";
import {Ownable} from "solady/auth/Ownable.sol";

contract GBR_OnlyOwner_Test is GalxeBadgeReceiverV2Test {
modifier onlyOwnerCanCall(address eve) {
vm.assume(eve != users.admin);
changePrank(eve);
vm.expectRevert(Ownable.Unauthorized.selector);
_;

changePrank(users.admin);
_;
}

function testFuzz_onlyOwner_UpdateValidNftAddr(address eve) public onlyOwnerCanCall(eve) {
galaxeBadgeReceiverV2.updateValidNftAddr(makeAddr("NFT"), true);
}

function testFuzz_onlyOwner_UpdateSigner(address eve) public onlyOwnerCanCall(eve) {
galaxeBadgeReceiverV2.updateSigner(users.signer, true);
}

function testFuzz_onlyOwner_UpdateDstValidity(address eve) public onlyOwnerCanCall(eve) {
galaxeBadgeReceiverV2.updateDstValidity(1, true);
}
}
19 changes: 19 additions & 0 deletions packages/dev/test/uint/shared/GalxeBadgeReceiverV2.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

import {BaseTest} from "test/Base.t.sol";
import {GalaxeBadgeReceiverV2} from "src/bridge/GalaxeBadgeReceiverV2.sol";
import {Ownable} from "solady/auth/Ownable.sol";

contract GalxeBadgeReceiverV2Test is BaseTest {
GalaxeBadgeReceiverV2 internal galaxeBadgeReceiverV2;

function setUp() public override {
super.setUp();
deploy();
}

function deploy() internal {
galaxeBadgeReceiverV2 = new GalaxeBadgeReceiverV2(users.admin, address(usdt));
}
}

0 comments on commit 3826260

Please sign in to comment.