Improved NFT tests
Now uses the ERC 721/1155 ABIs, gets selector automatically, and actually verifies the signature
This commit is contained in:
276
tests/ragger/abis/erc1155.json
Normal file
276
tests/ragger/abis/erc1155.json
Normal file
@@ -0,0 +1,276 @@
|
||||
[
|
||||
{
|
||||
"anonymous" : false,
|
||||
"inputs" : [
|
||||
{
|
||||
"indexed" : true,
|
||||
"internalType" : "address",
|
||||
"name" : "_owner",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"indexed" : true,
|
||||
"internalType" : "address",
|
||||
"name" : "_operator",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"indexed" : false,
|
||||
"internalType" : "bool",
|
||||
"name" : "_approved",
|
||||
"type" : "bool"
|
||||
}
|
||||
],
|
||||
"name" : "ApprovalForAll",
|
||||
"type" : "event"
|
||||
},
|
||||
{
|
||||
"anonymous" : false,
|
||||
"inputs" : [
|
||||
{
|
||||
"indexed" : true,
|
||||
"internalType" : "address",
|
||||
"name" : "_operator",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"indexed" : true,
|
||||
"internalType" : "address",
|
||||
"name" : "_from",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"indexed" : true,
|
||||
"internalType" : "address",
|
||||
"name" : "_to",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"indexed" : false,
|
||||
"internalType" : "uint256[]",
|
||||
"name" : "_ids",
|
||||
"type" : "uint256[]"
|
||||
},
|
||||
{
|
||||
"indexed" : false,
|
||||
"internalType" : "uint256[]",
|
||||
"name" : "_values",
|
||||
"type" : "uint256[]"
|
||||
}
|
||||
],
|
||||
"name" : "TransferBatch",
|
||||
"type" : "event"
|
||||
},
|
||||
{
|
||||
"anonymous" : false,
|
||||
"inputs" : [
|
||||
{
|
||||
"indexed" : true,
|
||||
"internalType" : "address",
|
||||
"name" : "_operator",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"indexed" : true,
|
||||
"internalType" : "address",
|
||||
"name" : "_from",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"indexed" : true,
|
||||
"internalType" : "address",
|
||||
"name" : "_to",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"indexed" : false,
|
||||
"internalType" : "uint256",
|
||||
"name" : "_id",
|
||||
"type" : "uint256"
|
||||
},
|
||||
{
|
||||
"indexed" : false,
|
||||
"internalType" : "uint256",
|
||||
"name" : "_value",
|
||||
"type" : "uint256"
|
||||
}
|
||||
],
|
||||
"name" : "TransferSingle",
|
||||
"type" : "event"
|
||||
},
|
||||
{
|
||||
"anonymous" : false,
|
||||
"inputs" : [
|
||||
{
|
||||
"indexed" : false,
|
||||
"internalType" : "string",
|
||||
"name" : "_value",
|
||||
"type" : "string"
|
||||
},
|
||||
{
|
||||
"indexed" : true,
|
||||
"internalType" : "uint256",
|
||||
"name" : "_id",
|
||||
"type" : "uint256"
|
||||
}
|
||||
],
|
||||
"name" : "URI",
|
||||
"type" : "event"
|
||||
},
|
||||
{
|
||||
"inputs" : [
|
||||
{
|
||||
"internalType" : "address",
|
||||
"name" : "_owner",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"internalType" : "uint256",
|
||||
"name" : "_id",
|
||||
"type" : "uint256"
|
||||
}
|
||||
],
|
||||
"name" : "balanceOf",
|
||||
"outputs" : [
|
||||
{
|
||||
"internalType" : "uint256",
|
||||
"name" : "",
|
||||
"type" : "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability" : "view",
|
||||
"type" : "function"
|
||||
},
|
||||
{
|
||||
"inputs" : [
|
||||
{
|
||||
"internalType" : "address[]",
|
||||
"name" : "_owners",
|
||||
"type" : "address[]"
|
||||
},
|
||||
{
|
||||
"internalType" : "uint256[]",
|
||||
"name" : "_ids",
|
||||
"type" : "uint256[]"
|
||||
}
|
||||
],
|
||||
"name" : "balanceOfBatch",
|
||||
"outputs" : [
|
||||
{
|
||||
"internalType" : "uint256[]",
|
||||
"name" : "",
|
||||
"type" : "uint256[]"
|
||||
}
|
||||
],
|
||||
"stateMutability" : "view",
|
||||
"type" : "function"
|
||||
},
|
||||
{
|
||||
"inputs" : [
|
||||
{
|
||||
"internalType" : "address",
|
||||
"name" : "_owner",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"internalType" : "address",
|
||||
"name" : "_operator",
|
||||
"type" : "address"
|
||||
}
|
||||
],
|
||||
"name" : "isApprovedForAll",
|
||||
"outputs" : [
|
||||
{
|
||||
"internalType" : "bool",
|
||||
"name" : "",
|
||||
"type" : "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability" : "view",
|
||||
"type" : "function"
|
||||
},
|
||||
{
|
||||
"inputs" : [
|
||||
{
|
||||
"internalType" : "address",
|
||||
"name" : "_from",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"internalType" : "address",
|
||||
"name" : "_to",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"internalType" : "uint256[]",
|
||||
"name" : "_ids",
|
||||
"type" : "uint256[]"
|
||||
},
|
||||
{
|
||||
"internalType" : "uint256[]",
|
||||
"name" : "_values",
|
||||
"type" : "uint256[]"
|
||||
},
|
||||
{
|
||||
"internalType" : "bytes",
|
||||
"name" : "_data",
|
||||
"type" : "bytes"
|
||||
}
|
||||
],
|
||||
"name" : "safeBatchTransferFrom",
|
||||
"outputs" : [],
|
||||
"stateMutability" : "nonpayable",
|
||||
"type" : "function"
|
||||
},
|
||||
{
|
||||
"inputs" : [
|
||||
{
|
||||
"internalType" : "address",
|
||||
"name" : "_from",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"internalType" : "address",
|
||||
"name" : "_to",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"internalType" : "uint256",
|
||||
"name" : "_id",
|
||||
"type" : "uint256"
|
||||
},
|
||||
{
|
||||
"internalType" : "uint256",
|
||||
"name" : "_value",
|
||||
"type" : "uint256"
|
||||
},
|
||||
{
|
||||
"internalType" : "bytes",
|
||||
"name" : "_data",
|
||||
"type" : "bytes"
|
||||
}
|
||||
],
|
||||
"name" : "safeTransferFrom",
|
||||
"outputs" : [],
|
||||
"stateMutability" : "nonpayable",
|
||||
"type" : "function"
|
||||
},
|
||||
{
|
||||
"inputs" : [
|
||||
{
|
||||
"internalType" : "address",
|
||||
"name" : "_operator",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"internalType" : "bool",
|
||||
"name" : "_approved",
|
||||
"type" : "bool"
|
||||
}
|
||||
],
|
||||
"name" : "setApprovalForAll",
|
||||
"outputs" : [],
|
||||
"stateMutability" : "nonpayable",
|
||||
"type" : "function"
|
||||
}
|
||||
]
|
||||
268
tests/ragger/abis/erc721.json
Normal file
268
tests/ragger/abis/erc721.json
Normal file
@@ -0,0 +1,268 @@
|
||||
[
|
||||
{
|
||||
"anonymous" : false,
|
||||
"inputs" : [
|
||||
{
|
||||
"indexed" : true,
|
||||
"internalType" : "address",
|
||||
"name" : "_owner",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"indexed" : true,
|
||||
"internalType" : "address",
|
||||
"name" : "_approved",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"indexed" : true,
|
||||
"internalType" : "uint256",
|
||||
"name" : "_tokenId",
|
||||
"type" : "uint256"
|
||||
}
|
||||
],
|
||||
"name" : "Approval",
|
||||
"type" : "event"
|
||||
},
|
||||
{
|
||||
"anonymous" : false,
|
||||
"inputs" : [
|
||||
{
|
||||
"indexed" : true,
|
||||
"internalType" : "address",
|
||||
"name" : "_owner",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"indexed" : true,
|
||||
"internalType" : "address",
|
||||
"name" : "_operator",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"indexed" : false,
|
||||
"internalType" : "bool",
|
||||
"name" : "_approved",
|
||||
"type" : "bool"
|
||||
}
|
||||
],
|
||||
"name" : "ApprovalForAll",
|
||||
"type" : "event"
|
||||
},
|
||||
{
|
||||
"anonymous" : false,
|
||||
"inputs" : [
|
||||
{
|
||||
"indexed" : true,
|
||||
"internalType" : "address",
|
||||
"name" : "_from",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"indexed" : true,
|
||||
"internalType" : "address",
|
||||
"name" : "_to",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"indexed" : true,
|
||||
"internalType" : "uint256",
|
||||
"name" : "_tokenId",
|
||||
"type" : "uint256"
|
||||
}
|
||||
],
|
||||
"name" : "Transfer",
|
||||
"type" : "event"
|
||||
},
|
||||
{
|
||||
"inputs" : [
|
||||
{
|
||||
"internalType" : "address",
|
||||
"name" : "_approved",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"internalType" : "uint256",
|
||||
"name" : "_tokenId",
|
||||
"type" : "uint256"
|
||||
}
|
||||
],
|
||||
"name" : "approve",
|
||||
"outputs" : [],
|
||||
"stateMutability" : "payable",
|
||||
"type" : "function"
|
||||
},
|
||||
{
|
||||
"inputs" : [
|
||||
{
|
||||
"internalType" : "address",
|
||||
"name" : "_owner",
|
||||
"type" : "address"
|
||||
}
|
||||
],
|
||||
"name" : "balanceOf",
|
||||
"outputs" : [
|
||||
{
|
||||
"internalType" : "uint256",
|
||||
"name" : "",
|
||||
"type" : "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability" : "view",
|
||||
"type" : "function"
|
||||
},
|
||||
{
|
||||
"inputs" : [
|
||||
{
|
||||
"internalType" : "uint256",
|
||||
"name" : "_tokenId",
|
||||
"type" : "uint256"
|
||||
}
|
||||
],
|
||||
"name" : "getApproved",
|
||||
"outputs" : [
|
||||
{
|
||||
"internalType" : "address",
|
||||
"name" : "",
|
||||
"type" : "address"
|
||||
}
|
||||
],
|
||||
"stateMutability" : "view",
|
||||
"type" : "function"
|
||||
},
|
||||
{
|
||||
"inputs" : [
|
||||
{
|
||||
"internalType" : "address",
|
||||
"name" : "_owner",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"internalType" : "address",
|
||||
"name" : "_operator",
|
||||
"type" : "address"
|
||||
}
|
||||
],
|
||||
"name" : "isApprovedForAll",
|
||||
"outputs" : [
|
||||
{
|
||||
"internalType" : "bool",
|
||||
"name" : "",
|
||||
"type" : "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability" : "view",
|
||||
"type" : "function"
|
||||
},
|
||||
{
|
||||
"inputs" : [
|
||||
{
|
||||
"internalType" : "uint256",
|
||||
"name" : "_tokenId",
|
||||
"type" : "uint256"
|
||||
}
|
||||
],
|
||||
"name" : "ownerOf",
|
||||
"outputs" : [
|
||||
{
|
||||
"internalType" : "address",
|
||||
"name" : "",
|
||||
"type" : "address"
|
||||
}
|
||||
],
|
||||
"stateMutability" : "view",
|
||||
"type" : "function"
|
||||
},
|
||||
{
|
||||
"inputs" : [
|
||||
{
|
||||
"internalType" : "address",
|
||||
"name" : "_from",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"internalType" : "address",
|
||||
"name" : "_to",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"internalType" : "uint256",
|
||||
"name" : "_tokenId",
|
||||
"type" : "uint256"
|
||||
}
|
||||
],
|
||||
"name" : "safeTransferFrom",
|
||||
"outputs" : [],
|
||||
"stateMutability" : "payable",
|
||||
"type" : "function"
|
||||
},
|
||||
{
|
||||
"inputs" : [
|
||||
{
|
||||
"internalType" : "address",
|
||||
"name" : "_from",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"internalType" : "address",
|
||||
"name" : "_to",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"internalType" : "uint256",
|
||||
"name" : "_tokenId",
|
||||
"type" : "uint256"
|
||||
},
|
||||
{
|
||||
"internalType" : "bytes",
|
||||
"name" : "data",
|
||||
"type" : "bytes"
|
||||
}
|
||||
],
|
||||
"name" : "safeTransferFrom",
|
||||
"outputs" : [],
|
||||
"stateMutability" : "payable",
|
||||
"type" : "function"
|
||||
},
|
||||
{
|
||||
"inputs" : [
|
||||
{
|
||||
"internalType" : "address",
|
||||
"name" : "_operator",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"internalType" : "bool",
|
||||
"name" : "_approved",
|
||||
"type" : "bool"
|
||||
}
|
||||
],
|
||||
"name" : "setApprovalForAll",
|
||||
"outputs" : [],
|
||||
"stateMutability" : "nonpayable",
|
||||
"type" : "function"
|
||||
},
|
||||
{
|
||||
"inputs" : [
|
||||
{
|
||||
"internalType" : "address",
|
||||
"name" : "_from",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"internalType" : "address",
|
||||
"name" : "_to",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"internalType" : "uint256",
|
||||
"name" : "_tokenId",
|
||||
"type" : "uint256"
|
||||
}
|
||||
],
|
||||
"name" : "transferFrom",
|
||||
"outputs" : [],
|
||||
"stateMutability" : "payable",
|
||||
"type" : "function"
|
||||
}
|
||||
]
|
||||
@@ -1,17 +1,21 @@
|
||||
import pytest
|
||||
from typing import Optional, Any
|
||||
from pathlib import Path
|
||||
from typing import Callable
|
||||
from ragger.error import ExceptionRAPDU
|
||||
from ragger.firmware import Firmware
|
||||
from ragger.backend import BackendInterface
|
||||
from ragger.navigator import Navigator, NavInsID
|
||||
from ledger_app_clients.ethereum.client import EthAppClient, TxData, StatusWord
|
||||
from ledger_app_clients.ethereum.settings import SettingID, settings_toggle
|
||||
from eth_utils import function_signature_to_4byte_selector
|
||||
import struct
|
||||
from ledger_app_clients.ethereum.client import EthAppClient, StatusWord
|
||||
import ledger_app_clients.ethereum.response_parser as ResponseParser
|
||||
from ledger_app_clients.ethereum.utils import get_selector_from_data, recover_transaction
|
||||
from web3 import Web3
|
||||
import json
|
||||
import os
|
||||
|
||||
|
||||
ROOT_SCREENSHOT_PATH = Path(__file__).parent
|
||||
ABIS_FOLDER = "%s/abis" % (os.path.dirname(__file__))
|
||||
|
||||
BIP32_PATH = "m/44'/60'/0'/0/0"
|
||||
NONCE = 21
|
||||
@@ -21,23 +25,25 @@ FROM = bytes.fromhex("1122334455667788990011223344556677889900")
|
||||
TO = bytes.fromhex("0099887766554433221100998877665544332211")
|
||||
NFTS = [ (1, 3), (5, 2), (7, 4) ] # tuples of (token_id, amount)
|
||||
DATA = "Some data".encode()
|
||||
DEVICE_ADDR: Optional[bytes] = None
|
||||
|
||||
class NFTCollection:
|
||||
addr: bytes
|
||||
name: str
|
||||
chain_id: int
|
||||
def __init__(self, addr: bytes, name: str, chain_id: int):
|
||||
def __init__(self, addr: bytes, name: str, chain_id: int, contract):
|
||||
self.addr = addr
|
||||
self.name = name
|
||||
self.chain_id = chain_id
|
||||
self.contract = contract
|
||||
|
||||
class Action:
|
||||
fn: str
|
||||
data_fn: Callable
|
||||
fn_name: str
|
||||
fn_args: list[Any]
|
||||
nav_fn: Callable
|
||||
def __init__(self, fn: str, data_fn: Callable, nav_fn: Callable):
|
||||
self.fn = fn
|
||||
self.data_fn = data_fn
|
||||
def __init__(self, fn_name: str, fn_args: list[Any], nav_fn: Callable):
|
||||
self.fn_name = fn_name
|
||||
self.fn_args = fn_args
|
||||
self.nav_fn = nav_fn
|
||||
|
||||
def common_nav_nft(is_nano: bool, nano_steps: int, stax_steps: int, reject: bool) -> list[NavInsID]:
|
||||
@@ -59,7 +65,7 @@ def common_nav_nft(is_nano: bool, nano_steps: int, stax_steps: int, reject: bool
|
||||
return moves
|
||||
|
||||
def snapshot_test_name(nft_type: str, fn: str, chain_id: int, reject: bool) -> str:
|
||||
name = "%s_%s_%s" % (nft_type, fn.split("(")[0], str(chain_id))
|
||||
name = "%s_%s_%s" % (nft_type, fn, str(chain_id))
|
||||
if reject:
|
||||
name += "-rejected"
|
||||
return name
|
||||
@@ -71,34 +77,48 @@ def common_test_nft(fw: Firmware,
|
||||
action: Action,
|
||||
reject: bool,
|
||||
plugin_name: str):
|
||||
global DEVICE_ADDR
|
||||
app_client = EthAppClient(back)
|
||||
selector = function_signature_to_4byte_selector(action.fn)
|
||||
|
||||
if app_client._client.firmware.name == "nanos":
|
||||
pytest.skip("Not supported on LNS")
|
||||
|
||||
if DEVICE_ADDR is None: # to only have to request it once
|
||||
with app_client.get_public_addr(display=False):
|
||||
pass
|
||||
_, DEVICE_ADDR, _ = ResponseParser.pk_addr(app_client.response().data)
|
||||
|
||||
data = collec.contract.encodeABI(action.fn_name, action.fn_args)
|
||||
with app_client.set_plugin(plugin_name,
|
||||
collec.addr,
|
||||
selector,
|
||||
1):
|
||||
get_selector_from_data(data),
|
||||
collec.chain_id):
|
||||
pass
|
||||
with app_client.provide_nft_metadata(collec.name, collec.addr, collec.chain_id):
|
||||
pass
|
||||
with app_client.sign_legacy(BIP32_PATH,
|
||||
NONCE,
|
||||
GAS_PRICE,
|
||||
GAS_LIMIT,
|
||||
collec.addr,
|
||||
0,
|
||||
collec.chain_id,
|
||||
action.data_fn(action)):
|
||||
tx_params = {
|
||||
"nonce": NONCE,
|
||||
"gasPrice": Web3.to_wei(GAS_PRICE, "gwei"),
|
||||
"gas": GAS_LIMIT,
|
||||
"to": collec.addr,
|
||||
"value": 0,
|
||||
"chainId": collec.chain_id,
|
||||
"data": data,
|
||||
}
|
||||
with app_client.sign(BIP32_PATH, tx_params):
|
||||
nav.navigate_and_compare(ROOT_SCREENSHOT_PATH,
|
||||
snapshot_test_name(plugin_name.lower(),
|
||||
action.fn,
|
||||
action.fn_name,
|
||||
collec.chain_id,
|
||||
reject),
|
||||
action.nav_fn(fw.is_nano,
|
||||
collec.chain_id,
|
||||
reject))
|
||||
# verify signature
|
||||
vrs = ResponseParser.signature(app_client.response().data)
|
||||
addr = recover_transaction(tx_params, vrs)
|
||||
assert addr == DEVICE_ADDR
|
||||
|
||||
|
||||
def common_test_nft_reject(test_fn: Callable,
|
||||
fw: Firmware,
|
||||
@@ -116,48 +136,14 @@ def common_test_nft_reject(test_fn: Callable,
|
||||
# ERC-721
|
||||
|
||||
ERC721_PLUGIN = "ERC721"
|
||||
ERC721_SAFE_TRANSFER_FROM_DATA = "safeTransferFrom(address,address,uint256,bytes)"
|
||||
ERC721_SAFE_TRANSFER_FROM = "safeTransferFrom(address,address,uint256)"
|
||||
ERC721_TRANSFER_FROM = "transferFrom(address,address,uint256)"
|
||||
ERC721_APPROVE = "approve(address,uint256)"
|
||||
ERC721_SET_APPROVAL_FOR_ALL = "setApprovalForAll(address,bool)"
|
||||
|
||||
## data formatting functions
|
||||
|
||||
def data_erc721_transfer_from(action: Action) -> TxData:
|
||||
return TxData(
|
||||
function_signature_to_4byte_selector(action.fn),
|
||||
[
|
||||
FROM,
|
||||
TO,
|
||||
struct.pack(">H", NFTS[0][0])
|
||||
]
|
||||
with open("%s/erc721.json" % (ABIS_FOLDER)) as file:
|
||||
contract_erc721 = Web3().eth.contract(
|
||||
abi=json.load(file),
|
||||
address=bytes(20)
|
||||
)
|
||||
|
||||
def data_erc721_safe_transfer_from_data(action: Action) -> TxData:
|
||||
txd = data_erc721_transfer_from(action)
|
||||
txd.parameters += [ DATA ]
|
||||
return txd
|
||||
|
||||
def data_erc721_approve(action: Action) -> TxData:
|
||||
return TxData(
|
||||
function_signature_to_4byte_selector(action.fn),
|
||||
[
|
||||
TO,
|
||||
struct.pack(">H", NFTS[0][0])
|
||||
]
|
||||
)
|
||||
|
||||
def data_erc721_set_approval_for_all(action: Action) -> TxData:
|
||||
return TxData(
|
||||
function_signature_to_4byte_selector(action.fn),
|
||||
[
|
||||
TO,
|
||||
struct.pack("b", False)
|
||||
]
|
||||
)
|
||||
|
||||
## ui nav functions
|
||||
# ui nav functions
|
||||
|
||||
def nav_erc721_transfer_from(is_nano: bool,
|
||||
chain_id: int,
|
||||
@@ -190,30 +176,33 @@ def nav_erc721_set_approval_for_all(is_nano: bool,
|
||||
collecs_721 = [
|
||||
NFTCollection(bytes.fromhex("bc4ca0eda7647a8ab7c2061c2e118a18a936f13d"),
|
||||
"Bored Ape Yacht Club",
|
||||
1),
|
||||
1,
|
||||
contract_erc721),
|
||||
NFTCollection(bytes.fromhex("670fd103b1a08628e9557cd66b87ded841115190"),
|
||||
"y00ts",
|
||||
137),
|
||||
137,
|
||||
contract_erc721),
|
||||
NFTCollection(bytes.fromhex("2909cf13e458a576cdd9aab6bd6617051a92dacf"),
|
||||
"goerlirocks",
|
||||
5)
|
||||
5,
|
||||
contract_erc721),
|
||||
]
|
||||
actions_721 = [
|
||||
Action(ERC721_SAFE_TRANSFER_FROM_DATA,
|
||||
data_erc721_safe_transfer_from_data,
|
||||
Action("safeTransferFrom",
|
||||
[FROM, TO, NFTS[0][0], DATA],
|
||||
nav_erc721_transfer_from),
|
||||
Action(ERC721_SAFE_TRANSFER_FROM,
|
||||
data_erc721_transfer_from,
|
||||
Action("safeTransferFrom",
|
||||
[FROM, TO, NFTS[0][0]],
|
||||
nav_erc721_transfer_from),
|
||||
Action(ERC721_TRANSFER_FROM,
|
||||
data_erc721_transfer_from,
|
||||
Action("transferFrom",
|
||||
[FROM, TO, NFTS[0][0]],
|
||||
nav_erc721_transfer_from),
|
||||
Action(ERC721_APPROVE,
|
||||
data_erc721_approve,
|
||||
Action("approve",
|
||||
[TO, NFTS[0][0]],
|
||||
nav_erc721_approve),
|
||||
Action(ERC721_SET_APPROVAL_FOR_ALL,
|
||||
data_erc721_set_approval_for_all,
|
||||
nav_erc721_set_approval_for_all)
|
||||
Action("setApprovalForAll",
|
||||
[TO, False],
|
||||
nav_erc721_set_approval_for_all),
|
||||
]
|
||||
|
||||
|
||||
@@ -251,51 +240,15 @@ def test_erc721_reject(firmware: Firmware,
|
||||
# ERC-1155
|
||||
|
||||
ERC1155_PLUGIN = "ERC1155"
|
||||
ERC1155_SAFE_TRANSFER_FROM = "safeTransferFrom(address,address,uint256,uint256,bytes)"
|
||||
ERC1155_SAFE_BATCH_TRANSFER_FROM = "safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)"
|
||||
ERC1155_SET_APPROVAL_FOR_ALL = "setApprovalForAll(address,bool)"
|
||||
|
||||
## data formatting functions
|
||||
|
||||
def data_erc1155_safe_transfer_from(action: Action) -> TxData:
|
||||
return TxData(
|
||||
function_signature_to_4byte_selector(action.fn),
|
||||
[
|
||||
FROM,
|
||||
TO,
|
||||
struct.pack(">H", NFTS[0][0]),
|
||||
struct.pack(">H", NFTS[0][1]),
|
||||
DATA
|
||||
]
|
||||
with open("%s/erc1155.json" % (ABIS_FOLDER)) as file:
|
||||
contract_erc1155 = Web3().eth.contract(
|
||||
abi=json.load(file),
|
||||
address=bytes(20)
|
||||
)
|
||||
|
||||
def data_erc1155_safe_batch_transfer_from(action: Action) -> TxData:
|
||||
data = TxData(
|
||||
function_signature_to_4byte_selector(action.fn),
|
||||
[
|
||||
FROM,
|
||||
TO
|
||||
])
|
||||
data.parameters += [ int(32 * 4).to_bytes(8, "big") ] # token_ids offset
|
||||
data.parameters += [int(32 * (4 + len(NFTS) + 1)).to_bytes(8, "big") ] # amounts offset
|
||||
data.parameters += [ int(len(NFTS)).to_bytes(8, "big") ] # token_ids length
|
||||
for nft in NFTS:
|
||||
data.parameters += [ struct.pack(">H", nft[0]) ] # token_id
|
||||
data.parameters += [ int(len(NFTS)).to_bytes(8, "big") ] # amounts length
|
||||
for nft in NFTS:
|
||||
data.parameters += [ struct.pack(">H", nft[1]) ] # amount
|
||||
return data
|
||||
|
||||
def data_erc1155_set_approval_for_all(action: Action) -> TxData:
|
||||
return TxData(
|
||||
function_signature_to_4byte_selector(action.fn),
|
||||
[
|
||||
TO,
|
||||
struct.pack("b", False)
|
||||
]
|
||||
)
|
||||
|
||||
## ui nav functions
|
||||
# ui nav functions
|
||||
|
||||
def nav_erc1155_safe_transfer_from(is_nano: bool,
|
||||
chain_id: int,
|
||||
@@ -326,24 +279,33 @@ def nav_erc1155_set_approval_for_all(is_nano: bool,
|
||||
collecs_1155 = [
|
||||
NFTCollection(bytes.fromhex("495f947276749ce646f68ac8c248420045cb7b5e"),
|
||||
"OpenSea Shared Storefront",
|
||||
1),
|
||||
1,
|
||||
contract_erc1155),
|
||||
NFTCollection(bytes.fromhex("2953399124f0cbb46d2cbacd8a89cf0599974963"),
|
||||
"OpenSea Collections",
|
||||
137),
|
||||
137,
|
||||
contract_erc1155),
|
||||
NFTCollection(bytes.fromhex("f4910c763ed4e47a585e2d34baa9a4b611ae448c"),
|
||||
"OpenSea Collections",
|
||||
5)
|
||||
5,
|
||||
contract_erc1155),
|
||||
]
|
||||
actions_1155 = [
|
||||
Action(ERC1155_SAFE_TRANSFER_FROM,
|
||||
data_erc1155_safe_transfer_from,
|
||||
Action("safeTransferFrom",
|
||||
[FROM, TO, NFTS[0][0], NFTS[0][1], DATA],
|
||||
nav_erc1155_safe_transfer_from),
|
||||
Action(ERC1155_SAFE_BATCH_TRANSFER_FROM,
|
||||
data_erc1155_safe_batch_transfer_from,
|
||||
Action("safeBatchTransferFrom",
|
||||
[
|
||||
FROM,
|
||||
TO,
|
||||
list(map(lambda nft: nft[0], NFTS)),
|
||||
list(map(lambda nft: nft[1], NFTS)),
|
||||
DATA
|
||||
],
|
||||
nav_erc1155_safe_batch_transfer_from),
|
||||
Action(ERC1155_SET_APPROVAL_FOR_ALL,
|
||||
data_erc1155_set_approval_for_all,
|
||||
nav_erc1155_set_approval_for_all)
|
||||
Action("setApprovalForAll",
|
||||
[TO, False],
|
||||
nav_erc1155_set_approval_for_all),
|
||||
]
|
||||
@pytest.fixture(params=collecs_1155)
|
||||
def collec_1155(request) -> bool:
|
||||
|
||||
Reference in New Issue
Block a user