Skip to content

Commit

Permalink
chore: merge with main
Browse files Browse the repository at this point in the history
  • Loading branch information
0xNeshi committed Nov 28, 2024
2 parents 10b8345 + 1244d38 commit 6a9e243
Show file tree
Hide file tree
Showing 35 changed files with 2,271 additions and 55 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,4 @@ jobs:
uses: actions/checkout@v4

- name: Check spelling of files in the workspace
uses: crate-ci/[email protected].0
uses: crate-ci/[email protected].1
13 changes: 4 additions & 9 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- `VestingWallet` contract. #402
- `Erc1155Burnable` extension. #417
- `Erc1155MetadataUri` extension. #416

### Changed

- Added `URI` event to `Erc1155`. #416
- Implement `MethodError` for `safe_erc20::Error`. #402
- Use `function_selector!` to calculate transfer type selector in `Erc1155`. #417

### Fixed

Expand All @@ -33,14 +36,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Removed `only_owner` from the public interface of `Ownable`. #352

### Changed

-

### Fixed

-

## [0.1.1] - 2024-10-28

### Changed
Expand Down
15 changes: 14 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ members = [
"examples/erc1155",
"examples/merkle-proofs",
"examples/ownable",
"examples/vesting-wallet",
"examples/access-control",
"examples/basic/token",
"examples/basic/script",
Expand All @@ -39,6 +40,7 @@ default-members = [
"examples/safe-erc20",
"examples/merkle-proofs",
"examples/ownable",
"examples/vesting-wallet",
"examples/ownable-two-step",
"examples/access-control",
"examples/basic/token",
Expand Down
2 changes: 1 addition & 1 deletion GUIDELINES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Setup

1. Install [Docker].
1. Install the [Solidity Compiler] version `0.8.24`
1. Install the [Solidity Compiler] version `0.8.24`.
(NOTE: it is important to use this exact version to avoid compatibility issues).
1. Install toolchain providing `cargo` using [rustup].
1. Install the cargo stylus tool with `cargo install --force cargo-stylus`.
Expand Down
1 change: 1 addition & 0 deletions benches/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ koba.workspace = true
e2e.workspace = true
serde = "1.0.203"
keccak-const = "0.2.0"
itertools = "0.13.0"
13 changes: 12 additions & 1 deletion benches/src/erc1155.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ sol!(
function safeBatchTransferFrom(address from, address to, uint256[] memory ids, uint256[] memory values, bytes memory data) external;
function mint(address to, uint256 id, uint256 amount, bytes memory data) external;
function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) external;
function burn(address account, uint256 id, uint256 value) external;
function burnBatch(address account, uint256[] memory ids, uint256[] memory values) external;
function uri(uint256 id) external view returns (string memory uri);
}
);
Expand Down Expand Up @@ -59,10 +61,16 @@ pub async fn run_with(

let bob = Account::new().await?;
let bob_addr = bob.address();
let bob_wallet = ProviderBuilder::new()
.network::<AnyNetwork>()
.with_recommended_fillers()
.wallet(EthereumWallet::from(bob.signer.clone()))
.on_http(bob.url().parse()?);

let contract_addr = deploy(&alice, cache_opt).await?;

let contract = Erc1155::new(contract_addr, &alice_wallet);
let contract_bob = Erc1155::new(contract_addr, &bob_wallet);

let token_1 = uint!(1_U256);
let token_2 = uint!(2_U256);
Expand Down Expand Up @@ -90,7 +98,10 @@ pub async fn run_with(
(setApprovalForAllCall::SIGNATURE, receipt!(contract.setApprovalForAll(bob_addr, true))?),
(isApprovedForAllCall::SIGNATURE, receipt!(contract.isApprovedForAll(alice_addr, bob_addr))?),
(safeTransferFromCall::SIGNATURE, receipt!(contract.safeTransferFrom(alice_addr, bob_addr, token_1, value_1, data.clone()))?),
(safeBatchTransferFromCall::SIGNATURE, receipt!(contract.safeBatchTransferFrom(alice_addr, bob_addr, ids, values, data.clone()))?),
(safeBatchTransferFromCall::SIGNATURE, receipt!(contract.safeBatchTransferFrom(alice_addr, bob_addr, ids.clone(), values.clone(), data))?),
// We should burn Bob's tokens on behalf of Bob, not Alice.
(burnCall::SIGNATURE, receipt!(contract_bob.burn(bob_addr, token_1, value_1))?),
(burnBatchCall::SIGNATURE, receipt!(contract_bob.burnBatch(bob_addr, ids, values))?),
(uriCall::SIGNATURE, receipt!(contract.uri(token_1))?),
];

Expand Down
2 changes: 2 additions & 0 deletions benches/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub mod erc721;
pub mod merkle_proofs;
pub mod ownable;
pub mod report;
pub mod vesting_wallet;

#[derive(Debug, Deserialize)]
struct ArbOtherFields {
Expand All @@ -32,6 +33,7 @@ struct ArbOtherFields {

/// Cache options for the contract.
/// `Bid(0)` will likely cache the contract on the nitro test node.
#[derive(Clone)]
pub enum CacheOpt {
None,
Bid(u32),
Expand Down
22 changes: 16 additions & 6 deletions benches/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
use benches::{
access_control, erc20, erc721, merkle_proofs, ownable,
access_control, erc1155, erc20, erc721, merkle_proofs, ownable,
report::BenchmarkReport,
};
use futures::FutureExt;
use itertools::Itertools;

#[tokio::main]
async fn main() -> eyre::Result<()> {
let report = futures::future::try_join_all([
let benchmarks = [
access_control::bench().boxed(),
erc20::bench().boxed(),
erc721::bench().boxed(),
merkle_proofs::bench().boxed(),
ownable::bench().boxed(),
])
.await?
.into_iter()
.fold(BenchmarkReport::default(), BenchmarkReport::merge_with);
erc1155::bench().boxed(),
];

// Run benchmarks max 3 at the same time.
// Otherwise, nitro test node can overload and revert transaction.
const MAX_PARALLEL: usize = 3;
let mut report = BenchmarkReport::default();
for chunk in &benchmarks.into_iter().chunks(MAX_PARALLEL) {
report = futures::future::try_join_all(chunk)
.await?
.into_iter()
.fold(report, BenchmarkReport::merge_with);
}

println!();
println!("{report}");
Expand Down
132 changes: 132 additions & 0 deletions benches/src/vesting_wallet.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
use alloy::{
network::{AnyNetwork, EthereumWallet},
primitives::Address,
providers::ProviderBuilder,
sol,
sol_types::{SolCall, SolConstructor},
uint,
};
use alloy_primitives::U256;
use e2e::{receipt, Account};

use crate::{
report::{ContractReport, FunctionReport},
CacheOpt,
};

sol!(
#[sol(rpc)]
contract VestingWallet {
function owner() public view virtual returns (address owner);
function receiveEther() external payable virtual;
function start() external view returns (uint256 start);
function duration() external view returns (uint256 duration);
function end() external view returns (uint256 end);
function released() external view returns (uint256 released);
function released(address token) external view returns (uint256 released);
function releasable() external view returns (uint256 releasable);
function releasable(address token) external view returns (uint256 releasable);
function release() external;
function release(address token) external;
function vestedAmount(uint64 timestamp) external view returns (uint256 vestedAmount);
function vestedAmount(address token, uint64 timestamp) external view returns (uint256 vestedAmount);
}

#[sol(rpc)]
contract Erc20 {
function mint(address account, uint256 amount) external;
}
);

sol!("../examples/vesting-wallet/src/constructor.sol");
sol!("../examples/erc20/src/constructor.sol");

const START_TIMESTAMP: u64 = 1000;
const DURATION_SECONDS: u64 = 1000;

const TOKEN_NAME: &str = "Test Token";
const TOKEN_SYMBOL: &str = "TTK";
const CAP: U256 = uint!(1_000_000_U256);

pub async fn bench() -> eyre::Result<ContractReport> {
let reports = run_with(CacheOpt::None).await?;
let report = reports
.into_iter()
.try_fold(ContractReport::new("VestingWallet"), ContractReport::add)?;

let cached_reports = run_with(CacheOpt::Bid(0)).await?;
let report = cached_reports
.into_iter()
.try_fold(report, ContractReport::add_cached)?;

Ok(report)
}

pub async fn run_with(
cache_opt: CacheOpt,
) -> eyre::Result<Vec<FunctionReport>> {
let alice = Account::new().await?;
let alice_wallet = ProviderBuilder::new()
.network::<AnyNetwork>()
.with_recommended_fillers()
.wallet(EthereumWallet::from(alice.signer.clone()))
.on_http(alice.url().parse()?);

let contract_addr = deploy(&alice, cache_opt.clone()).await?;
let erc20_addr = deploy_token(&alice, cache_opt).await?;

let contract = VestingWallet::new(contract_addr, &alice_wallet);
let erc20 = Erc20::new(erc20_addr, &alice_wallet);

let _ = receipt!(contract.receiveEther().value(uint!(1000_U256)))?;
let _ = receipt!(erc20.mint(contract_addr, uint!(1000_U256)))?;

// IMPORTANT: Order matters!
use VestingWallet::*;
#[rustfmt::skip]
let receipts = vec![
(receiveEtherCall::SIGNATURE, receipt!(contract.receiveEther())?),
(startCall::SIGNATURE, receipt!(contract.start())?),
(durationCall::SIGNATURE, receipt!(contract.duration())?),
(endCall::SIGNATURE, receipt!(contract.end())?),
(released_0Call::SIGNATURE, receipt!(contract.released_0())?),
(released_1Call::SIGNATURE, receipt!(contract.released_1(erc20_addr))?),
(releasable_0Call::SIGNATURE, receipt!(contract.releasable_0())?),
(releasable_1Call::SIGNATURE, receipt!(contract.releasable_1(erc20_addr))?),
(release_0Call::SIGNATURE, receipt!(contract.release_0())?),
(release_1Call::SIGNATURE, receipt!(contract.release_1(erc20_addr))?),
(vestedAmount_0Call::SIGNATURE, receipt!(contract.vestedAmount_0(START_TIMESTAMP))?),
(vestedAmount_1Call::SIGNATURE, receipt!(contract.vestedAmount_1(erc20_addr, START_TIMESTAMP))?),
];

receipts
.into_iter()
.map(FunctionReport::new)
.collect::<eyre::Result<Vec<_>>>()
}

async fn deploy(
account: &Account,
cache_opt: CacheOpt,
) -> eyre::Result<Address> {
let args = VestingWalletExample::constructorCall {
beneficiary: account.address(),
startTimestamp: START_TIMESTAMP,
durationSeconds: DURATION_SECONDS,
};
let args = alloy::hex::encode(args.abi_encode());
crate::deploy(account, "vesting-wallet", Some(args), cache_opt).await
}

async fn deploy_token(
account: &Account,
cache_opt: CacheOpt,
) -> eyre::Result<Address> {
let args = Erc20Example::constructorCall {
name_: TOKEN_NAME.to_owned(),
symbol_: TOKEN_SYMBOL.to_owned(),
cap_: CAP,
};
let args = alloy::hex::encode(args.abi_encode());
crate::deploy(account, "erc20", Some(args), cache_opt).await
}
2 changes: 2 additions & 0 deletions contracts/src/finance/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
//! Primitives for financial systems.
pub mod vesting_wallet;
Loading

0 comments on commit 6a9e243

Please sign in to comment.