#![cfg(feature = "provider")]
use tronz_contract::{SolCall as _, tron_sol};
use tronz_primitives::{Address, Bytes, U256};
use tronz_provider::TronProvider;
tron_sol! {
#[sol(rpc)]
#[tron_sol(tronz_crate = ::tronz_contract)]
interface IERC20 {
function name() external view returns (string);
function decimals() external view returns (uint8);
function totalSupply() external view returns (uint256);
function balanceOf(address owner) external view returns (uint256);
function allowance(address owner, address spender) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
}
#[test]
fn type_layer_encoding() {
let owner: Address = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t".parse().unwrap();
let call = IERC20::balanceOfCall { owner: owner.into() };
let encoded = call.abi_encode();
assert_eq!(&encoded[..4], &IERC20::balanceOfCall::SELECTOR);
assert_eq!(encoded.len(), 36);
}
#[test]
fn return_type_decode() {
let mut out = [0u8; 32];
out[31] = 42;
assert_eq!(IERC20::balanceOfCall::abi_decode_returns(&out).unwrap(), U256::from(42u64),);
}
#[allow(dead_code, clippy::unused_async)]
async fn _erc20_api<P: TronProvider + Clone>(provider: P, addr: Address) {
let token = IERC20::new(addr, provider);
let _: String = token.name().call().await.unwrap();
let _: u8 = token.decimals().call().await.unwrap();
let _: U256 = token.totalSupply().call().await.unwrap();
let _: U256 = token.balanceOf(addr).call().await.unwrap();
let _: U256 = token.allowance(addr, addr).call().await.unwrap();
let _ = token.transfer(addr, U256::ZERO).send().await;
let _ = token.approve(addr, U256::ZERO).send().await;
let _ = token.transferFrom(addr, addr, U256::ZERO).send().await;
let _ = token.balanceOf(addr).estimate_energy().await;
let _ = token.address();
let _ = token.clone().at(addr);
let _ = token.call_builder(&IERC20::balanceOfCall { owner: addr.into() }).call().await;
}
#[allow(dead_code)]
fn _instance_is_debug<P: TronProvider>() {
fn assert_debug<T: core::fmt::Debug>() {}
assert_debug::<IERC20::Instance<P>>();
}
tron_sol! {
#[sol(rpc)]
#[tron_sol(tronz_crate = ::tronz_contract)]
interface IERC721 is IBase {
function ownerOf(uint256 tokenId) external view returns (address);
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function safeTransferFrom(address from, address to, uint256 tokenId, bytes data) external;
}
}
#[test]
fn overloaded_selectors_differ() {
assert_ne!(
IERC721::safeTransferFrom_0Call::SELECTOR,
IERC721::safeTransferFrom_1Call::SELECTOR,
);
}
#[allow(dead_code, clippy::unused_async)]
async fn _erc721_api<P: TronProvider + Clone>(provider: P, addr: Address) {
let nft = IERC721::new(addr, provider);
let _ = nft.ownerOf(U256::ZERO).call().await;
let _ = nft.safeTransferFrom_0(addr, addr, U256::ZERO).send().await;
let _ = nft.safeTransferFrom_1(addr, addr, U256::ZERO, Bytes::new()).send().await;
}
tron_sol! {
#[sol(rpc)]
#[tron_sol(tronz_crate = ::tronz_contract)]
interface IPool {
type Shares is uint256;
function deposit(Shares amount) external returns (Shares);
}
}
#[allow(dead_code, clippy::unused_async)]
async fn _udvt_maps_to_underlying<P: TronProvider + Clone>(provider: P, addr: Address) {
let pool = IPool::new(addr, provider);
let _ = pool.deposit(U256::ZERO).send().await;
}
tron_sol! {
#[sol(rpc)]
#[tron_sol(tronz_crate = ::tronz_contract)]
interface IKeywordParams {
function configure(uint256 ref, address move, bool box) external;
}
}
#[allow(dead_code, clippy::unused_async)]
async fn _keyword_params<P: TronProvider + Clone>(provider: P, addr: Address) {
let c = IKeywordParams::new(addr, provider);
let _ = c.configure(U256::ZERO, addr, true).send().await;
}
tron_sol! {
#[sol(rpc, bytecode = "0x6080604052", deployed_bytecode = "0x6080604051")]
#[tron_sol(tronz_crate = ::tronz_contract)]
contract SimpleToken {
constructor(uint256 supply);
function totalSupply() external view returns (uint256);
}
}
#[test]
fn bytecode_is_embedded() {
assert_eq!(&SimpleToken::BYTECODE[..], &[0x60, 0x80, 0x60, 0x40, 0x52]);
}
#[test]
fn deployed_bytecode_is_embedded() {
assert_eq!(&SimpleToken::DEPLOYED_BYTECODE[..], &[0x60, 0x80, 0x60, 0x40, 0x51]);
}
#[allow(dead_code, clippy::unused_async)]
async fn _deploy_api<P: TronProvider + Clone>(provider: P) {
let _ = SimpleToken::deploy_builder(provider.clone(), U256::from(1000u64));
let _ = SimpleToken::deploy(provider, U256::from(1000u64)).await;
}
tron_sol! {
#[sol(rpc)]
#[tron_sol(tronz_crate = ::tronz_contract)]
interface IReserved {
function address() external view returns (address);
function at(uint256 slot) external view returns (bytes32);
function provider() external view returns (address);
}
}
#[test]
fn reserved_names_get_call_suffix() {
let _ = IReserved::addressCall {};
let _ = IReserved::providerCall {};
}
#[allow(dead_code, clippy::unused_async)]
async fn _reserved_api<P: TronProvider + Clone>(provider: P, addr: Address) {
let c = IReserved::new(addr, provider);
let _: Address = c.address();
let _ = c.clone().at(addr);
let _: &P = c.provider();
let _ = c.address_call().call().await;
let _ = c.at_call(U256::ZERO).call().await;
let _ = c.provider_call().call().await;
}
tron_sol! {
#[tron_sol(tronz_crate = ::tronz_contract)]
struct Order {
address maker;
uint256 amount;
}
enum Side {
Buy,
Sell,
}
#[sol(rpc)]
interface IExchange {
function place(Order order, Side side) external returns (uint256 id);
}
#[sol(rpc)]
interface IRegistry {
function lookup(uint256 id) external view returns (address);
}
}
#[test]
fn multiple_items_one_invocation() {
let owner: Address = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t".parse().unwrap();
let _order = Order { maker: owner.into(), amount: U256::from(7u64) };
let _side = Side::Buy;
let _ = IExchange::placeCall::SELECTOR;
let _ = IRegistry::lookupCall::SELECTOR;
}
#[allow(dead_code, clippy::unused_async)]
async fn _multi_instance_api<P: TronProvider + Clone>(provider: P, addr: Address) {
let exchange = IExchange::new(addr, provider.clone());
let _ =
exchange.place(Order { maker: addr.into(), amount: U256::ZERO }, Side::Sell).call().await;
let registry = IRegistry::new(addr, provider);
let _ = registry.lookup(U256::ZERO).call().await;
}
tron_sol! {
#[tron_sol(tronz_crate = ::tronz_contract)]
#[derive(Debug, Default, PartialEq)]
struct Point {
int256 x;
int256 y;
}
#[derive(Debug)]
#[sol(rpc)]
interface IPoints {
function set(Point p) external;
}
}
#[test]
fn attributes_pass_through() {
let a = Point::default();
let b = Point { x: Default::default(), y: Default::default() };
assert_eq!(a, b);
let _ = format!("{a:?}");
let _ = format!("{:?}", IPoints::setCall { p: Point::default() });
}
tron_sol! {
#[sol(rpc)]
#[tron_sol(tronz_crate = ::tronz_contract)]
contract IVault {
uint256 public totalDeposits;
address public owner;
function deposit(uint256 amount) external;
}
}
#[test]
fn public_state_var_selectors_exist() {
let _ = IVault::totalDepositsCall::SELECTOR;
let _ = IVault::ownerCall::SELECTOR;
}
#[allow(dead_code, clippy::unused_async)]
async fn _vault_getters<P: TronProvider + Clone>(provider: P, addr: Address) {
let vault = IVault::new(addr, provider);
let _: U256 = vault.totalDeposits().call().await.unwrap();
let _ = vault.owner().call().await.unwrap(); }
tron_sol! {
#[sol(rpc)]
#[tron_sol(tronz_crate = ::tronz_contract)]
interface IToken {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function transfer(address to, uint256 amount) external returns (bool);
}
}
#[allow(dead_code, clippy::unused_async)]
async fn _event_filter_api<P: TronProvider + Clone>(provider: P, addr: Address) {
use tronz_primitives::B256;
let token = IToken::new(addr, provider);
let _filter = token.event_filter::<IToken::Transfer>();
let _tf = token.Transfer_filter();
let _af = token.Approval_filter();
let _tf2 = token.Transfer_filter().address(addr);
let tx_id = B256::ZERO;
let _: Vec<IToken::Transfer> = _tf.query_tx(tx_id).await.unwrap();
let _: Vec<IToken::Transfer> = token.Transfer_filter().query_block(0).await.unwrap();
}
tron_sol! {
#[sol(rpc)]
#[tron_sol(tronz_crate = ::tronz_contract)]
IERC20Json, "tests/abi/erc20.json"
}
#[test]
fn json_abi_type_layer_encoding() {
let owner: Address = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t".parse().unwrap();
let call = IERC20Json::balanceOfCall { owner: owner.into() };
let encoded = call.abi_encode();
assert_eq!(&encoded[..4], &IERC20Json::balanceOfCall::SELECTOR);
assert_eq!(encoded.len(), 36);
}
#[allow(dead_code, clippy::unused_async)]
async fn _json_abi_rpc_api<P: TronProvider + Clone>(provider: P, addr: Address) {
let token = IERC20Json::new(addr, provider);
let _: String = token.name().call().await.unwrap();
let _: u8 = token.decimals().call().await.unwrap();
let _: U256 = token.totalSupply().call().await.unwrap();
let _: U256 = token.balanceOf(addr).call().await.unwrap();
let _ = token.transfer(addr, U256::ZERO).send().await;
}
tron_sol! {
#[sol(rpc)]
#[tron_sol(tronz_crate = ::tronz_contract)]
IForgeArtifact, "tests/abi/erc20_forge.json"
}
#[test]
fn forge_artifact_matches_raw_array() {
assert_eq!(IForgeArtifact::totalSupplyCall::SIGNATURE, IERC20Json::totalSupplyCall::SIGNATURE);
assert_eq!(IForgeArtifact::balanceOfCall::SIGNATURE, IERC20Json::balanceOfCall::SIGNATURE);
}
tron_sol! {
#![sol(all_derives)]
#[sol(rpc)]
#[tron_sol(tronz_crate = ::tronz_contract)]
IInnerAttr, "tests/abi/erc20.json"
}
#[test]
fn inner_attr_all_derives() {
let owner: Address = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t".parse().unwrap();
let call = IInnerAttr::balanceOfCall { owner: owner.into() };
let _ = format!("{call:?}");
let _ = call.clone();
}