Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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
3 changes: 1 addition & 2 deletions Cargo.lock

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

46 changes: 0 additions & 46 deletions crates/contracts/build.rs

This file was deleted.

10 changes: 0 additions & 10 deletions crates/contracts/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,6 @@ pub fn testing_contract_error() -> MethodError {
}
}

/// Create an arbitrary alloy error that will convert into a "contract" error. Useful for testing.
pub fn testing_alloy_contract_error() -> alloy::contract::Error {
alloy::contract::Error::NotADeploymentTransaction
}

/// Create an arbitrary alloy error that will convert into a "node" error. Useful for testing.
pub fn testing_alloy_node_error() -> alloy::contract::Error {
alloy::contract::Error::TransportError(alloy::transports::TransportError::NullResp)
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
10 changes: 0 additions & 10 deletions crates/contracts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,6 @@ pub mod paths;
pub mod vault;
pub mod web3;

macro_rules! include_contracts {
($($name:ident;)*) => {$(
include!(concat!(env!("OUT_DIR"), "/", stringify!($name), ".rs"));
)*};
}

include_contracts! {
ERC20;
}

#[cfg(test)]
mod tests {
use {
Expand Down
8 changes: 4 additions & 4 deletions crates/cow-amm/src/maintainers.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use {
crate::{Amm, cache::Storage},
contracts::ERC20,
contracts::alloy::ERC20,
ethcontract::futures::future::{join_all, select_ok},
ethrpc::{Web3, alloy::conversions::IntoLegacy},
ethrpc::Web3,
shared::maintenance::Maintaining,
std::sync::Arc,
tokio::sync::RwLock,
Expand All @@ -25,8 +25,8 @@ impl EmptyPoolRemoval {
.traded_tokens()
.iter()
.map(move |token| async move {
ERC20::at(&self.web3, token.into_legacy())
.balance_of(amm_address.into_legacy())
ERC20::Instance::new(*token, self.web3.alloy.clone())
.balanceOf(*amm_address)
.call()
.await
.map_err(|err| {
Expand Down
13 changes: 1 addition & 12 deletions crates/driver/src/infra/blockchain/contracts.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use {
crate::{domain::eth, infra::blockchain::Ethereum},
crate::domain::eth,
chain::Chain,
contracts::alloy::{
BalancerV2Vault,
Expand Down Expand Up @@ -183,17 +183,6 @@ pub fn deployment_address(
)
}

/// A trait for initializing contract instances with dynamic addresses.
pub trait ContractAt {
fn at(eth: &Ethereum, address: eth::ContractAddress) -> Self;
}

impl ContractAt for contracts::ERC20 {
fn at(eth: &Ethereum, address: eth::ContractAddress) -> Self {
Self::at(&eth.web3, address.into())
}
}

#[derive(Debug, Error)]
pub enum Error {
#[error("method error: {0:?}")]
Expand Down
6 changes: 0 additions & 6 deletions crates/driver/src/infra/blockchain/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use {
self::contracts::ContractAt,
crate::{boundary, domain::eth},
chain::Chain,
ethcontract::{U256, errors::ExecutionError},
Expand Down Expand Up @@ -159,11 +158,6 @@ impl Ethereum {
&self.inner.contracts
}

/// Create a contract instance at the specified address.
pub fn contract_at<T: ContractAt>(&self, address: eth::ContractAddress) -> T {
T::at(self, address)
}

/// Check if a smart contract is deployed to the given address.
pub async fn is_contract(&self, address: eth::Address) -> Result<bool, Error> {
let code = self.web3.eth().code(address.into(), None).await?;
Expand Down
49 changes: 27 additions & 22 deletions crates/driver/src/infra/blockchain/token.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
use {
super::{Error, Ethereum},
crate::domain::eth,
ethrpc::alloy::{
conversions::{IntoAlloy, IntoLegacy},
errors::ContractErrorExt,
},
};

/// An ERC-20 token.
///
/// https://eips.ethereum.org/EIPS/eip-20
pub struct Erc20 {
token: contracts::ERC20,
token: contracts::alloy::ERC20::Instance,
}

impl Erc20 {
pub(super) fn new(eth: &Ethereum, address: eth::TokenAddress) -> Self {
Self {
token: eth.contract_at(address.into()),
token: contracts::alloy::ERC20::Instance::new(
address.0.0.into_alloy(),
eth.web3.alloy.clone(),
),
}
}

/// Returns the [`eth::TokenAddress`] of the ERC20.
pub fn address(&self) -> eth::TokenAddress {
self.token.address().into()
self.token.address().into_legacy().into()
}

/// Fetch the ERC20 allowance for the spender. See the allowance method in
Expand All @@ -31,11 +38,15 @@ impl Erc20 {
owner: eth::Address,
spender: eth::Address,
) -> Result<eth::allowance::Existing, Error> {
let amount = self.token.allowance(owner.0, spender.0).call().await?;
let amount = self
.token
.allowance(owner.0.into_alloy(), spender.0.into_alloy())
.call()
.await?;
Ok(eth::Allowance {
token: self.token.address().into(),
token: self.token.address().into_legacy().into(),
spender,
amount,
amount: amount.into_legacy(),
}
.into())
}
Expand All @@ -47,8 +58,10 @@ impl Erc20 {
pub async fn decimals(&self) -> Result<Option<u8>, Error> {
match self.token.decimals().call().await {
Ok(decimals) => Ok(Some(decimals)),
Err(err) if is_contract_error(&err) => Ok(None),
Err(err) => Err(err.into()),
// Check for the transport because if a method is not available it returns an empty
// response that doesn't decode to a proper contract error
Err(err) if err.is_transport_error() => Err(err.into()),
Err(_) => Ok(None),
}
}

Expand All @@ -59,8 +72,10 @@ impl Erc20 {
pub async fn symbol(&self) -> Result<Option<String>, Error> {
match self.token.symbol().call().await {
Ok(symbol) => Ok(Some(symbol)),
Err(err) if is_contract_error(&err) => Ok(None),
Err(err) => Err(err.into()),
// Check for the transport because if a method is not available it returns an empty
// response that doesn't decode to a proper contract error
Err(err) if err.is_transport_error() => Err(err.into()),
Err(_) => Ok(None),
}
}

Expand All @@ -70,21 +85,11 @@ impl Erc20 {
/// https://eips.ethereum.org/EIPS/eip-20#balanceof
pub async fn balance(&self, holder: eth::Address) -> Result<eth::TokenAmount, Error> {
self.token
.balance_of(holder.0)
.balanceOf(holder.0.into_alloy())
.call()
.await
.map(IntoLegacy::into_legacy)
.map(Into::into)
.map_err(Into::into)
}
}

/// Returns `true` if a [`ethcontract::errors::MethodError`] is the result of
/// some on-chain computation error.
fn is_contract_error(err: &ethcontract::errors::MethodError) -> bool {
// Assume that any error that isn't a `Web3` error is a "contract error",
// this can mean things like:
// - The contract call reverted
// - The returndata cannot be decoded
// - etc.
!matches!(&err.inner, ethcontract::errors::ExecutionError::Web3(_))
}
10 changes: 6 additions & 4 deletions crates/e2e/src/setup/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,12 +250,14 @@ async fn run<F, Fut, T>(
#[macro_export]
macro_rules! assert_approximately_eq {
($executed_value:expr_2021, $expected_value:expr_2021) => {{
let lower = $expected_value * U256::from(99999999999u128) / U256::from(100000000000u128);
let upper =
($expected_value * U256::from(100000000001u128) / U256::from(100000000000u128)) + 1;
let lower = $expected_value * ::alloy::primitives::U256::from(99999999999u128)
/ ::alloy::primitives::U256::from(100000000000u128);
let upper = ($expected_value * ::alloy::primitives::U256::from(100000000001u128)
/ ::alloy::primitives::U256::from(100000000000u128))
+ ::alloy::primitives::U256::ONE;
assert!(
$executed_value >= lower && $executed_value <= upper,
"Expected: ~{}, got: {}",
"Expected: ~{}, got: {}, ({lower}, {upper})",
$expected_value,
$executed_value
);
Expand Down
2 changes: 1 addition & 1 deletion crates/e2e/tests/e2e/buffers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ async fn onchain_settlement_without_liquidity(web3: Web3) {
.await
.unwrap();
// Check that internal buffers were used
assert!(settlement_contract_balance == U256::ZERO);
assert_eq!(settlement_contract_balance, U256::ZERO);

// Same order can trade again with external liquidity
let order = OrderCreation {
Expand Down
Loading
Loading