Skip to content

Commit 6066d25

Browse files
committed
chain/ethereum: Allow hardcoded addresses in declared eth_calls
1 parent cd806e5 commit 6066d25

File tree

2 files changed

+30
-17
lines changed

2 files changed

+30
-17
lines changed

chain/ethereum/src/data_source.rs

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1676,6 +1676,7 @@ impl CallDecl {
16761676
fn address(&self, log: &Log, params: &[LogParam]) -> Result<H160, Error> {
16771677
let address = match &self.expr.address {
16781678
CallArg::Address => log.address,
1679+
CallArg::HexAddress(address) => *address,
16791680
CallArg::Param(name) => {
16801681
let value = params
16811682
.iter()
@@ -1697,6 +1698,7 @@ impl CallDecl {
16971698
.iter()
16981699
.map(|arg| match arg {
16991700
CallArg::Address => Ok(Token::Address(log.address)),
1701+
CallArg::HexAddress(address) => Ok(Token::Address(*address)),
17001702
CallArg::Param(name) => {
17011703
let value = params
17021704
.iter()
@@ -1795,32 +1797,31 @@ impl FromStr for CallExpr {
17951797

17961798
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
17971799
pub enum CallArg {
1800+
HexAddress(Address),
17981801
Address,
17991802
Param(Word),
18001803
}
18011804

1805+
lazy_static! {
1806+
// Matches a 40-character hexadecimal string prefixed with '0x', typical for Ethereum addresses
1807+
static ref ADDR_RE: Regex = Regex::new(r"^0x[0-9a-fA-F]{40}$").unwrap();
1808+
}
1809+
18021810
impl FromStr for CallArg {
18031811
type Err = anyhow::Error;
18041812

18051813
fn from_str(s: &str) -> Result<Self, Self::Err> {
1806-
fn invalid(s: &str) -> Result<CallArg, anyhow::Error> {
1807-
Err(anyhow!("invalid call argument `{}`", s))
1814+
if ADDR_RE.is_match(s) {
1815+
if let Ok(parsed_address) = Address::from_str(s) {
1816+
return Ok(CallArg::HexAddress(parsed_address));
1817+
}
18081818
}
18091819

1810-
let mut parts = s.split(".");
1811-
match parts.next() {
1812-
Some("event") => { /* ok */ }
1813-
Some(_) => return Err(anyhow!("call arguments must start with `event`")),
1814-
None => return Err(anyhow!("empty call argument")),
1815-
}
1816-
match parts.next() {
1817-
Some("address") => Ok(CallArg::Address),
1818-
Some("params") => match parts.next() {
1819-
Some(s) => Ok(CallArg::Param(Word::from(s))),
1820-
None => invalid(s),
1821-
},
1822-
Some(s) => invalid(s),
1823-
None => invalid(s),
1820+
let mut parts = s.split('.');
1821+
match (parts.next(), parts.next(), parts.next()) {
1822+
(Some("event"), Some("address"), None) => Ok(CallArg::Address),
1823+
(Some("event"), Some("params"), Some(param)) => Ok(CallArg::Param(Word::from(param))),
1824+
_ => Err(anyhow!("invalid call argument `{}`", s)),
18241825
}
18251826
}
18261827
}
@@ -1854,4 +1855,14 @@ fn test_call_expr() {
18541855
assert_eq!(expr.address, CallArg::Address);
18551856
assert_eq!(expr.func, "growth");
18561857
assert_eq!(expr.args, vec![]);
1858+
1859+
let expr: CallExpr = "Pool[0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF].growth(0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF)"
1860+
.parse()
1861+
.unwrap();
1862+
let call_arg =
1863+
CallArg::HexAddress(H160::from_str("0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF").unwrap());
1864+
assert_eq!(expr.abi, "Pool");
1865+
assert_eq!(expr.address, call_arg);
1866+
assert_eq!(expr.func, "growth");
1867+
assert_eq!(expr.args, vec![call_arg]);
18571868
}

store/test-store/tests/chain/ethereum/manifest.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1409,6 +1409,8 @@ dataSources:
14091409
calls:
14101410
fake1: Factory[event.address].get(event.params.address)
14111411
fake2: Factory[event.params.address].get(event.params.address)
1412+
fake3: Factory[0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF].get(event.address)
1413+
fake4: Factory[0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF].get(0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF)
14121414
";
14131415

14141416
test_store::run_test_sequentially(|store| async move {
@@ -1440,6 +1442,6 @@ dataSources:
14401442
// For more detailed tests of parsing CallDecls see the data_soure
14411443
// module in chain/ethereum
14421444
let decls = &ds.mapping.event_handlers[0].calls.decls;
1443-
assert_eq!(2, decls.len());
1445+
assert_eq!(4, decls.len());
14441446
});
14451447
}

0 commit comments

Comments
 (0)