Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: XCC token refund #802

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft

Conversation

Tarnadas
Copy link

@Tarnadas Tarnadas commented Jul 21, 2023

Motivation

I've been integrating the Aurora SDK in my orderbook implementation on Near (not yet open source) to do XCC from Aurora to Near, however there is one essential thing missing which are refunds on token transfers.

Imagine the following two scenarios:

Scenario 1:

  • Solidity contract bridges ERC-20 from Aurora to Near
  • XCC precompile sends ft_transfer or ft_transfer_call to FT contract
  • receipt at FT contract fails (e.g. because XCC address did not pay storage deposit)
  • FT are stuck in XCC address on Near

Scenario 2:

  • Solidity contract bridges ERC-20 from Aurora to Near
  • XCC precompile sends ft_transfer_call to FT contract
  • FT contract sends ft_on_transfer to receiver contract (e.g. a DEX)
  • receiver contract receipt fails (e.g. because of slippage)
  • FT contract calls ft_resolve_transfer and does the refund to XCC address
  • FT are stuck in XCC address on Near

Tokens being stuck without the possibility for a recovery is unacceptable for obvious reasons. Receipts can easily fail as you can see in scenario 2 where slippage constraint might not be met.

I have been in contact with @birchmd for quite a while to help me integrate Aurora SDK into the orderbook contract and everything works really good so far except the lack of refund. The orderbook I develop will be an upcoming product of Orderly Network. I really want to emphasize how essential a refund mechanism for bridged FT is. Without it you basically can't use Aurora SDK in DeFi.

Solution

My solution is WIP and I need help to fully implement it.
Let me demonstrate the solution for the updated scenario 2:

  • bridge, ft_transfer_call, ft_on_transfer receipt fail, ft_resolve_transfer refund to XCC
  • XCC address calls ft_transfer_call to Aurora engine address to bridge FT back to EVM address
    • we can calculate the unused tokens that need to be refund, because ft_resolve_transfer returns the used amount of tokens. If the receipt failed no tokens at all have been used.

I stumbled across the following problems:

  1. we don't know in the XCC contract what the EVM address is for the refund
  • (Solution): we need to extend the PromiseCreateArgs to also include the EVM sender address
  1. it seems like the XCC account no longer gets created with my changes and all I can see is a revert of the Aurora tx, but the Near tx seems to succeed
  • no solution so far, but I am clearly missing a change to update the input of the Near call to also include the sender. Where do I need to look for this?
  • already kind of fixed, but debugging further. It seems like I blew the size of the XCC contract so that it can no longer be deployed
  • I could shrink the binary size down by using wasm-opt. I haven't seen any usage of wasm-opt in your codebase and was wondering why you're not using it. With this command wasm-opt -Oz target/wasm32-unknown-unknown/release/xcc_router.wasm -o target/wasm32-unknown-unknown/release/xcc_router_opt.wasm --strip-debug --vacuum I shrinked the binary size from 219KB to 183KB and storage staking is now sufficient with 2NEAR. Also keep in mind that only wasm-opt v110 generates proper binary output for Near Protocol. Any newer version produces unusable WASM files. Not sure about a workaround though.

(As a side note I have some problems compiling rocksdb even though I have llvm and clang installed. Not sure what's the exact problem, but if I check out the most recent rocksdb from crates.io it can be compiled. Maybe worth looking into upgrading the dep?)

I know this is quite a drastic change and I haven't created a prior AIP. Please let me know what we need to do to get this implemented.

TODOs

  • finish ft_transfer_call refund
  • implement ft_transfer refund
  • investigate all affected tests
  • implement XCC contract upgrade mechanism

@Tarnadas Tarnadas force-pushed the develop branch 2 times, most recently from bed43f5 to 1f122f5 Compare July 21, 2023 21:08
@aleksuss aleksuss requested a review from birchmd July 22, 2023 11:35
@Tarnadas Tarnadas force-pushed the develop branch 12 times, most recently from 6d191d9 to ce851d3 Compare July 24, 2023 09:28
@Tarnadas
Copy link
Author

I got it almost working, but I don't seem to be able to get the address of the original tx signer. It's not part of the Context and there is currently no way to retrieve it.

let args = PromiseArgsWithSender {
sender: *context.address.as_fixed_bytes(),
args: call,
};

I first thought context.caller should be correct, but then I've seen that it's the address of the Solidity contract.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant