| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- use crate::build_solidity;
- use ethabi::{ethereum_types::U256, Token};
- use rand::Rng;
- #[test]
- fn interfaceid() {
- let mut vm = build_solidity(
- r#"
- contract foo {
- function get() public returns (bytes4) {
- return type(I).interfaceId;
- }
- }
- interface I {
- function bar(int) external;
- function baz(bytes) external returns (int);
- }"#,
- );
- vm.constructor("foo", &[]);
- let returns = vm.function("get", &[], &[], None);
- assert_eq!(
- returns,
- vec![Token::FixedBytes(0xc78d9f3au32.to_be_bytes().to_vec())]
- );
- }
- #[test]
- fn write_buffer() {
- let mut vm = build_solidity(
- r#"
- contract foo {
- function test1() public returns (bytes) {
- bytes bs = new bytes(12);
- bs.writeInt32LE(-0x41424344, 0);
- bs.writeUint64LE(0x0102030405060708, 4);
- return bs;
- }
- function test2() public returns (bytes) {
- bytes bs = new bytes(34);
- bs.writeUint16LE(0x4142, 0);
- bs.writeAddress(msg.sender, 2);
- return bs;
- }
- function test3() public returns (bytes) {
- bytes bs = new bytes(9);
- bs.writeUint64LE(1, 2);
- return bs;
- }
- }"#,
- );
- vm.constructor("foo", &[]);
- let returns = vm.function("test1", &[], &[], None);
- assert_eq!(
- returns,
- vec![Token::Bytes(
- [0xbc, 0xbc, 0xbd, 0xbe, 8, 7, 6, 5, 4, 3, 2, 1].to_vec()
- )]
- );
- let returns = vm.function("test2", &[], &[], None);
- let mut buf = vec![0x42u8, 0x41u8];
- buf.extend_from_slice(&vm.origin);
- assert_eq!(returns, vec![Token::Bytes(buf)]);
- let res = vm.function_must_fail("test3", &[], &[], None);
- assert_eq!(res, Ok(4294967296));
- }
- #[test]
- fn read_buffer() {
- let mut vm = build_solidity(
- r#"
- contract foo {
- function test1(bytes bs) public returns (int32, uint64) {
- return (bs.readInt32LE(0), bs.readUint64LE(4));
- }
- function test2(bytes bs) public returns (uint16, address) {
- return (bs.readUint16LE(0), bs.readAddress(2));
- }
- }"#,
- );
- vm.constructor("foo", &[]);
- let returns = vm.function(
- "test1",
- &[Token::Bytes(
- [0xbc, 0xbc, 0xbd, 0xbe, 8, 7, 6, 5, 4, 3, 2, 1].to_vec(),
- )],
- &[],
- None,
- );
- assert_eq!(
- returns,
- vec![
- Token::Int(U256::from(
- "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffbebdbcbc"
- )),
- Token::Uint(U256::from(0x0102030405060708u64))
- ]
- );
- let res = vm.function_must_fail(
- "test1",
- &[Token::Bytes(
- [0xbc, 0xbc, 0xbd, 0xbe, 8, 7, 6, 5, 4, 3, 2].to_vec(),
- )],
- &[],
- None,
- );
- assert_eq!(res, Ok(4294967296));
- let mut buf = vec![0x42u8, 0x41u8];
- buf.extend_from_slice(&vm.origin);
- let returns = vm.function("test2", &[Token::Bytes(buf.clone())], &[], None);
- assert_eq!(
- returns,
- vec![
- Token::Uint(U256::from(0x4142)),
- Token::FixedBytes(vm.origin.to_vec())
- ]
- );
- buf.pop();
- let res = vm.function_must_fail("test2", &[Token::Bytes(buf)], &[], None);
- assert_eq!(res, Ok(4294967296));
- }
- #[test]
- fn bytes_compare() {
- let mut vm = build_solidity(
- r#"
- contract foo {
- function test1(bytes4 bs) public returns (bool) {
- return bs != 0;
- }
- function test2(bytes4 bs) public returns (bool) {
- return bs == 0;
- }
- }"#,
- );
- vm.constructor("foo", &[]);
- let returns = vm.function(
- "test1",
- &[Token::FixedBytes([0xbc, 0xbc, 0xbd, 0xbe].to_vec())],
- &[],
- None,
- );
- assert_eq!(returns, vec![Token::Bool(true)]);
- let returns = vm.function(
- "test2",
- &[Token::FixedBytes([0xbc, 0xbc, 0xbd, 0xbe].to_vec())],
- &[],
- None,
- );
- assert_eq!(returns, vec![Token::Bool(false)]);
- }
- #[test]
- fn assignment_in_ternary() {
- let mut rng = rand::thread_rng();
- let mut vm = build_solidity(
- r#"
- contract foo {
- function minimum(uint64 x, uint64 y) public pure returns (uint64 z) {
- x >= y ? z = y : z = x;
- }
- }"#,
- );
- vm.constructor("foo", &[]);
- for _ in 0..10 {
- let left = rng.gen::<u64>();
- let right = rng.gen::<u64>();
- let returns = vm.function(
- "minimum",
- &[
- Token::Uint(U256::from(left)),
- Token::Uint(U256::from(right)),
- ],
- &[],
- None,
- );
- assert_eq!(
- returns,
- vec![Token::Uint(U256::from(std::cmp::min(left, right)))]
- );
- }
- }
- #[test]
- fn power() {
- let mut vm = build_solidity(
- r#"
- contract foo {
- function power() public returns (uint) {
- return 2 ** 3 ** 4;
- }
- }"#,
- );
- vm.constructor("foo", &[]);
- let returns = vm.function("power", &[], &[], None);
- assert_eq!(
- returns,
- vec![Token::Uint(U256::from(2417851639229258349412352u128))]
- );
- }
|