Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add LibBytes.sol #155

Merged
merged 1 commit into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 51 additions & 24 deletions onchain/rollups/test/foundry/dapp/CartesiDApp.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";

import {LibServerManager} from "../util/LibServerManager.sol";
import {LibBytes} from "../util/LibBytes.sol";
import {SimpleConsensus} from "../util/SimpleConsensus.sol";
import {SimpleERC20} from "../util/SimpleERC20.sol";
import {SimpleERC721} from "../util/SimpleERC721.sol";
Expand Down Expand Up @@ -73,17 +74,16 @@ contract CartesiDAppTest is TestBase {

bytes encodedFinishEpochResponse;

uint256 constant initialSupply = 1000000;
uint256 constant transferAmount = 7;
uint256 constant tokenId = uint256(keccak256("tokenId"));
IInputBox constant inputBox =
IInputBox(address(bytes20(keccak256("inputBox"))));
address constant dappOwner = address(bytes20(keccak256("dappOwner")));
address constant tokenOwner = address(bytes20(keccak256("tokenOwner")));
address constant recipient = address(bytes20(keccak256("recipient")));
address constant noticeSender = address(bytes20(keccak256("noticeSender")));
bytes32 constant salt = keccak256("salt");
bytes32 constant templateHash = keccak256("templateHash");
IInputBox immutable inputBox;
address immutable dappOwner;
address immutable noticeSender;
address immutable recipient;
address immutable tokenOwner;
bytes32 immutable salt;
bytes32 immutable templateHash;
uint256 immutable initialSupply;
uint256 immutable tokenId;
uint256 immutable transferAmount;

event VoucherExecuted(uint256 voucherPosition);
event OwnershipTransferred(
Expand All @@ -92,6 +92,21 @@ contract CartesiDAppTest is TestBase {
);
event NewConsensus(IConsensus newConsensus);

constructor() {
dappOwner = LibBytes.hashToAddress("dappOwner");
initialSupply = LibBytes.hashToUint256("initialSupply");
inputBox = IInputBox(LibBytes.hashToAddress("inputBox"));
noticeSender = LibBytes.hashToAddress("noticeSender");
recipient = LibBytes.hashToAddress("recipient");
salt = keccak256("salt");
templateHash = keccak256("templateHash");
tokenId = LibBytes.hashToUint256("tokenId");
tokenOwner = LibBytes.hashToAddress("tokenOwner");
transferAmount =
LibBytes.hashToUint256("transferAmount") %
(initialSupply + 1);
}

function setUp() public {
deployContracts();
generateOutputs();
Expand Down Expand Up @@ -161,9 +176,12 @@ contract CartesiDAppTest is TestBase {
// test vouchers

function testExecuteVoucherAndEvent(
uint256 _dappInitBalance,
uint256 _inputIndex,
uint256 _numInputsAfter
) public {
_dappInitBalance = boundBalance(_dappInitBalance);

Voucher memory voucher = getVoucher(OutputName.ERC20TransferVoucher);
Proof memory proof = setupVoucherProof(
OutputName.ERC20TransferVoucher,
Expand All @@ -180,10 +198,9 @@ contract CartesiDAppTest is TestBase {
assertEq(erc20Token.balanceOf(recipient), 0);

// fund dapp
uint256 dappInitBalance = 100;
vm.prank(tokenOwner);
erc20Token.transfer(address(dapp), dappInitBalance);
assertEq(erc20Token.balanceOf(address(dapp)), dappInitBalance);
erc20Token.transfer(address(dapp), _dappInitBalance);
assertEq(erc20Token.balanceOf(address(dapp)), _dappInitBalance);
assertEq(erc20Token.balanceOf(recipient), 0);

// expect event
Expand All @@ -201,15 +218,18 @@ contract CartesiDAppTest is TestBase {
// check result
assertEq(
erc20Token.balanceOf(address(dapp)),
dappInitBalance - transferAmount
_dappInitBalance - transferAmount
);
assertEq(erc20Token.balanceOf(recipient), transferAmount);
}

function testRevertsReexecution(
uint256 _dappInitBalance,
uint256 _inputIndex,
uint256 _numInputsAfter
) public {
_dappInitBalance = boundBalance(_dappInitBalance);

Voucher memory voucher = getVoucher(OutputName.ERC20TransferVoucher);
Proof memory proof = setupVoucherProof(
OutputName.ERC20TransferVoucher,
Expand All @@ -218,9 +238,8 @@ contract CartesiDAppTest is TestBase {
);

// fund dapp
uint256 dappInitBalance = 100;
vm.prank(tokenOwner);
erc20Token.transfer(address(dapp), dappInitBalance);
erc20Token.transfer(address(dapp), _dappInitBalance);

// 1st execution attempt should succeed
executeVoucher(voucher, proof);
Expand All @@ -232,15 +251,18 @@ contract CartesiDAppTest is TestBase {
// end result should be the same as executing successfully only once
assertEq(
erc20Token.balanceOf(address(dapp)),
dappInitBalance - transferAmount
_dappInitBalance - transferAmount
);
assertEq(erc20Token.balanceOf(recipient), transferAmount);
}

function testWasVoucherExecuted(
uint256 _dappInitBalance,
uint128 _inputIndex,
uint128 _numInputsAfter
) public {
_dappInitBalance = boundBalance(_dappInitBalance);

Voucher memory voucher = getVoucher(OutputName.ERC20TransferVoucher);
Proof memory proof = setupVoucherProof(
OutputName.ERC20TransferVoucher,
Expand All @@ -267,9 +289,8 @@ contract CartesiDAppTest is TestBase {
assertEq(executed, false);

// execute voucher - succeeded
uint256 dappInitBalance = 100;
vm.prank(tokenOwner);
erc20Token.transfer(address(dapp), dappInitBalance);
erc20Token.transfer(address(dapp), _dappInitBalance);
executeVoucher(voucher, proof);

// after executing voucher, `wasVoucherExecuted` should return true
Expand Down Expand Up @@ -379,9 +400,12 @@ contract CartesiDAppTest is TestBase {
// test ether transfer

function testEtherTransfer(
uint256 _dappInitBalance,
uint256 _inputIndex,
uint256 _numInputsAfter
) public {
_dappInitBalance = boundBalance(_dappInitBalance);

Voucher memory voucher = getVoucher(OutputName.ETHWithdrawalVoucher);
Proof memory proof = setupVoucherProof(
OutputName.ETHWithdrawalVoucher,
Expand All @@ -398,9 +422,8 @@ contract CartesiDAppTest is TestBase {
assertEq(address(recipient).balance, 0);

// fund dapp
uint256 dappInitBalance = 100;
vm.deal(address(dapp), dappInitBalance);
assertEq(address(dapp).balance, dappInitBalance);
vm.deal(address(dapp), _dappInitBalance);
assertEq(address(dapp).balance, _dappInitBalance);
assertEq(address(recipient).balance, 0);

// expect event
Expand All @@ -416,7 +439,7 @@ contract CartesiDAppTest is TestBase {
executeVoucher(voucher, proof);

// check result
assertEq(address(dapp).balance, dappInitBalance - transferAmount);
assertEq(address(dapp).balance, _dappInitBalance - transferAmount);
assertEq(address(recipient).balance, transferAmount);

// cannot execute the same voucher again
Expand Down Expand Up @@ -973,4 +996,8 @@ contract CartesiDAppTest is TestBase {
abi.encode(epochHash, firstInputIndex, lastInputIndex)
);
}

function boundBalance(uint256 _balance) internal view returns (uint256) {
return bound(_balance, transferAmount, initialSupply);
}
}
20 changes: 20 additions & 0 deletions onchain/rollups/test/foundry/util/LibBytes.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// (c) Cartesi and individual authors (see AUTHORS)
// SPDX-License-Identifier: Apache-2.0 (see LICENSE)

pragma solidity ^0.8.8;

library LibBytes {
/// @notice Generate an address from a byte array.
/// @param data The byte array
/// @return The address
function hashToAddress(bytes memory data) internal pure returns (address) {
return address(bytes20(keccak256(data)));
}

/// @notice Generate a 256-bit unsigned integer from a byte array.
/// @param data The byte array
/// @return The 256-bit unsigned integer
function hashToUint256(bytes memory data) internal pure returns (uint256) {
return uint256(keccak256(data));
}
}