Thanks for sharing this. I just took a look, and there’s a lot of stuff in there.
I’m gonna focus on transaction atomicity and try to figure out whether this proposed interface can solve the standard DEX user journey.
In this user journey, we have the following entities:
- Alice, who wants to swap Token A for Token B
- Token A canister
- Token B canister
- DEX canister (assume there’s only one canister for simplicity)
Now, this is the typical ERC-20 flow that would work on Ethereum:
- Alice calls
approveon Token A canister to let DEX canister transfer some number of Token As on her behalf
- Alice calls some custom function (e.g.
swap) on DEX canister to initiate the swap, which does the following:
a. DEX canister calls
transferFromon Token A canister to transfer Token As from Alice’s address to the DEX canister’s address (to add to its Token A reserves)
b. DEX canister internally calculates how many Token Bs Alice should get based on some formula like x * y = k
c. DEX canister calls
transferon Token B canister to transfer Token Bs from DEX canister’s address to Alice’s address (which subtracts from its Token B reserves)
d. DEX canister returns
swapcall if steps 2a, 2b, and 2c were successful; otherwise, it returns
falseand the whole transaction is atomically rolled back
- The DEX canister makes 2 inter-canister calls:
transfer. This example assumes that inter-canister calls are atomic because they are in Ethereum. On IC, they are not.
transferFromis used for Token A but
transferis used for Token B. This is intentional because the only 3rd party transfer (i.e. Alice authorizing DEX canister to transfer on her behalf) happens for Token A. For Token B, the entity that owns the tokens and who initiates the transaction is one and the same, i.e. DEX canister.