Skip to content

Commit c5c3f42

Browse files
committed
Add value test
1 parent c914951 commit c5c3f42

File tree

4 files changed

+77
-2
lines changed

4 files changed

+77
-2
lines changed

integration/stylus/value.sol

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity >=0.8.0;
3+
4+
contract C {
5+
function test() public payable returns (uint256) {
6+
return this.other{value: msg.value}();
7+
}
8+
9+
function other() public payable returns (uint256) {
10+
uint256 value = msg.value;
11+
print("value = {}".format(value));
12+
assert(value == 1000000000000000000);
13+
return value;
14+
}
15+
}

src/emit/stylus/target.rs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -840,7 +840,17 @@ impl<'a> TargetRuntime<'a> for StylusTarget {
840840
bin.builder
841841
.build_store(value, contract_args.value.unwrap())
842842
.unwrap();
843-
args.push(value.into());
843+
// smoelius: Value is little-endian and must be byte-swapped.
844+
let temp = bin.builder.build_alloca(bin.value_type(), "value").unwrap();
845+
call!(
846+
"__leNtobeN",
847+
&[
848+
value.into(),
849+
temp.into(),
850+
i32_const!(bin.ns.value_length as u64).into()
851+
]
852+
);
853+
args.push(temp.into())
844854
}
845855

846856
let gas = gas_calculation(bin, contract_args.gas.unwrap());
@@ -1221,6 +1231,10 @@ impl<'a> TargetRuntime<'a> for StylusTarget {
12211231

12221232
timestamp.into()
12231233
}
1234+
Expression::Builtin {
1235+
kind: Builtin::Value,
1236+
..
1237+
} => self.value_transferred(bin).into(),
12241238
_ => unimplemented!("{expr:?}"),
12251239
}
12261240
}
@@ -1270,7 +1284,28 @@ impl<'a> TargetRuntime<'a> for StylusTarget {
12701284

12711285
/// Return the value we received
12721286
fn value_transferred<'b>(&self, bin: &Binary<'b>) -> IntValue<'b> {
1273-
unimplemented!()
1287+
emit_context!(bin);
1288+
1289+
let value = bin.builder.build_alloca(bin.value_type(), "value").unwrap();
1290+
1291+
call!("msg_value", &[value.into()], "value_transferred");
1292+
1293+
// smoelius: `value` is big-endian and must be byte-swapped.
1294+
let temp = bin.builder.build_alloca(bin.value_type(), "value").unwrap();
1295+
1296+
call!(
1297+
"__beNtoleN",
1298+
&[
1299+
value.into(),
1300+
temp.into(),
1301+
i32_const!(bin.ns.value_length as u64).into()
1302+
]
1303+
);
1304+
1305+
bin.builder
1306+
.build_load(bin.value_type(), temp, "value")
1307+
.unwrap()
1308+
.into_int_value()
12741309
}
12751310

12761311
/// Terminate execution, destroy bin and send remaining funds to addr

tests/stylus_tests/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ mod counter;
33
mod milestone_1;
44
mod milestone_2;
55
mod milestone_3;
6+
mod value;

tests/stylus_tests/value.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//! This test expects you to have a devnode running:
2+
//! <https://docs.arbitrum.io/run-arbitrum-node/run-nitro-dev-node>
3+
//!
4+
//! It also expects `cargo-stylus` and `cast` to be installed:
5+
//! - <https://github.com/OffchainLabs/cargo-stylus>
6+
//! - <https://book.getfoundry.sh/cast/>
7+
#![warn(clippy::pedantic)]
8+
9+
use crate::{deploy, send, MUTEX};
10+
use std::path::PathBuf;
11+
12+
#[test]
13+
fn value() {
14+
let _lock = MUTEX.lock();
15+
let (tempdir, address) = deploy(
16+
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("integration/stylus/value.sol"),
17+
"C",
18+
)
19+
.unwrap();
20+
let dir = &tempdir;
21+
22+
let stdout = send(dir, &address, ["test()", "--value=1000000000000000000"]).unwrap();
23+
println!("{}", &stdout);
24+
}

0 commit comments

Comments
 (0)