2

the solidity data structure and code is as follows :


struct Order {
        bytes32 sender;
        int128 priceX18;
        int128 amount;
        uint64 expiration;
        uint64 nonce;
 }

 struct SignedOrder {
        Order order;
        bytes signature;
 }
    
struct MatchOrderAMM {
        uint32 productId;
        int128 baseDelta;
        int128 quoteDelta;
        SignedOrder taker;
}

and in solidity code the abi decode is done like so :

function processTransaction(bytes calldata transaction) internal {

        TransactionType txType = TransactionType(uint8(transaction[0]));

       if (txType == TransactionType.MatchOrderAMM) {
            MatchOrderAMM memory txn = abi.decode(
                transaction[1:],
                (MatchOrderAMM)
            );
    }
}

and with ethers on web 2 i do this :

let tx = ethers.utils.concat([
       ethers.utils.arrayify(TransactionType.MatchOrderAMM),
       ethers.utils.defaultAbiCoder.encode(
         [
           {
             type: "tuple",
             name: "MatchOrderAMM",
             components: [
               {
                 type: "tuple",
                 name: "taker",
                 components: [
                   {
                     type: "tuple",
                     name: "order",
                     components: [
                       {
                         name: "sender",
                         type: "bytes32",
                       },
                       {
                         name: "amount",
                         type: "int128",
                       },
                       {
                         name: "priceX18",
                         type: "int128",
                       },
                       {
                         name: "expiration",
                         type: "uint64",
                       },
                       {
                         name: "nonce",
                         type: "uint64",
                       },
                     ],
                   },
                   {
                     name: "signature",
                     type: "bytes",
                   },
                 ],
               },
               {
                 name: "productId",
                 type: "uint32",
               },
               {
                 name: "baseDelta",
                 type: "int128",
               },
               {
                 name: "quoteDelta",
                 type: "int128",
               },
             ],
           } as any,
         ],
         [
           {
             taker: transaction.taker,
             productId: "1",
             baseDelta: transaction.baseDelta,
             quoteDelta: transaction.quoteDelta,
           },
         ]
       ),
])

the encoding completes with no issues but onchain/in solidity it is not decoding an error occors please help me verify if the ethers web2 encoding is dont properly. especially with the type that us defined for encoding

1 Answer 1

0

Try to avoid memory-consuming abi.decode() call, by just casting bytes to struct and enjoy gas-free decoding fields on the flight:

function processTransaction(bytes calldata transaction) internal {
    TransactionType txType = TransactionType(uint8(transaction[0]));
    if (txType == TransactionType.MatchOrderAMM) {
        MatchOrderAMM calldata txn;
        assembly ("memory-safe") {
            txn := transaction.offset
        }
    }
}

More info about this trick here: https://x.com/k06a/status/1706934230779883656

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.