Skip to content

Commit

Permalink
test: Add smart contract setup for testing
Browse files Browse the repository at this point in the history
  • Loading branch information
drklee3 committed Apr 17, 2024
1 parent 084ecbb commit 45b0d18
Show file tree
Hide file tree
Showing 12 changed files with 7,583 additions and 0 deletions.
14 changes: 14 additions & 0 deletions contract/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
node_modules
.env

# Hardhat files
/cache
/artifacts

# TypeChain files
/typechain
/typechain-types

# solidity-coverage files
/coverage
/coverage.json
11 changes: 11 additions & 0 deletions contract/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Test Contracts

Smart contracts used for testing.

```shell
npx hardhat help
npx hardhat test
REPORT_GAS=true npx hardhat test
npx hardhat node
npx hardhat run scripts/deploy.ts
```
49 changes: 49 additions & 0 deletions contract/contracts/EIP161Test.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract EIP161Test {
function selfDestructTo(address target) public payable {
// This contract will self-destruct and send its balance to the target address
selfdestruct(payable(target));
}

function selfDestructToRevert(address target) public payable {
// This contract will self-destruct and send its balance to the target address
selfdestruct(payable(target));

revert();
}

function callAccount(address target) public payable returns (bytes memory) {
(bool success, bytes memory data) = target.call{value: msg.value}("");
require(success, "Failed to call empty account with value");

return data;
}

function callAccountRevert(address target) public payable {
callAccount(target);
revert();
}

function createContract() public payable returns (address) {
address newContract;
bytes memory bytecode = hex"3859818153F3";
assembly {
newContract := create(0, add(bytecode, 0x20), mload(bytecode))
if iszero(extcodesize(newContract)) {
revert(0, 0)
}
}
return newContract;
}

function transferValue(address target) public payable {
payable(target).transfer(msg.value);
}

function transferValueRevert(address target) public payable {
transferValue(target);
revert();
}
}
34 changes: 34 additions & 0 deletions contract/contracts/Lock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.24;

// Uncomment this line to use console.log
// import "hardhat/console.sol";

contract Lock {
uint public unlockTime;
address payable public owner;

event Withdrawal(uint amount, uint when);

constructor(uint _unlockTime) payable {
require(
block.timestamp < _unlockTime,
"Unlock time should be in the future"
);

unlockTime = _unlockTime;
owner = payable(msg.sender);
}

function withdraw() public {
// Uncomment this line, and the import of "hardhat/console.sol", to print a log in your terminal
// console.log("Unlock time is %o and block timestamp is %o", unlockTime, block.timestamp);

require(block.timestamp >= unlockTime, "You can't withdraw yet");
require(msg.sender == owner, "You aren't the owner");

emit Withdrawal(address(this).balance, block.timestamp);

owner.transfer(address(this).balance);
}
}
41 changes: 41 additions & 0 deletions contract/contracts/StateTest.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.24;

// Uncomment this line to use console.log
// import "hardhat/console.sol";

// This contract is used to test the state of the EVM, specifically ensuring the
// StateDB Set/GetState methods behave as expected.
contract StateTest {
uint256 public value1;
uint256 public value2 = 0x1234;

function tempChangeEmpty(uint256 _value) public {
// Start from an empty state
require(value1 == 0, "Value is should be empty");
require(value2 != 0, "New value should be non-empty");

// Change to a non-empty state
value1 = _value;

// Revert back to an empty state to create an overall no-op change.
value1 = 0;

// Ensure value1 is still empty
require(value1 == 0, "Value should be empty");
}

function tempChangeNonEmpty(uint256 _value) public {
require(value2 != 0, "Existing value should be non-empty");
require(_value != 0, "New value should be non-empty");

// Change to an empty state
value2 = 0;

// Revert back to an non-empty state
value2 = _value;

// Ensure value2 is still non-empty
require(value2 != 0, "Value is empty");
}
}
37 changes: 37 additions & 0 deletions contract/genEthermintJSON.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/bash

# Exit on first error
set -e

# Check if jq is installed
if ! [ -x "$(command -v jq)" ]; then
echo "Error: jq is not installed." >&2
exit 1
fi

if [ $# -lt 2 ]; then
echo "Please specify: [path/to/artifacts/.json] [path/to/output/.json]"
exit 1
fi

# Check if $1 exists
if [ ! -f "$1" ]; then
echo "File not found: $1"
exit 1
fi

# Confirm if $2 exists
if [ -f "$2" ]; then
read -p "File exists: $2. Overwrite? (y/n) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
fi

# Convert artifact to the correct format Ethermint can use
jq '{ abi: .abi | tostring, bin: .bytecode | ltrimstr("0x")}' \
"$1" \
> "$2"

echo "Generated Ethermint JSON file at $2"
8 changes: 8 additions & 0 deletions contract/hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";

const config: HardhatUserConfig = {
solidity: "0.8.24",
};

export default config;
Loading

0 comments on commit 45b0d18

Please sign in to comment.