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

Support calculating the amount of TCO2 redeemed based on POOL #38

Open
kosecki123 opened this issue Jan 25, 2024 · 10 comments · May be fixed by #40
Open

Support calculating the amount of TCO2 redeemed based on POOL #38

kosecki123 opened this issue Jan 25, 2024 · 10 comments · May be fixed by #40
Assignees

Comments

@kosecki123
Copy link
Contributor

kosecki123 commented Jan 25, 2024

This issue tracks the missing functionality of calculating the amount of TCO2 received via redemption when providing POOL amount. Which is opposite to what's available rn.

This should be implemented as an additional option, not to replace existing feature.

#35 (comment)

@kosecki123
Copy link
Contributor Author

kosecki123 commented Jan 25, 2024

@0xmichalis One thing to note is that we can't calculate exact amount of POOL that's requested by user, the reason is the method we implement this is by iteratively searching for TCO2 that would yield the closest POOL amount.
Due to caping the amount of iteration we probably won't land of exact numer like 10POOL, but rather something like

9.99934 POOL - 9.123 TCO2

@kosecki123
Copy link
Contributor Author

kosecki123 commented Jan 25, 2024

On top of above, we may need to have this estimation function outside the redeemInMany call due to gas usage. So the flow would be

call estimateTCO2(uint256 poolAmount) returns uint256 -> estimatedTCO2
call redeemInMany(estimatedTCO2, maxPOOLamount, ....)

where maxPOOLamount would check that the result is not exceeding that amount in redeemInMany after making redemption - similarly to slippage protection in uniswap.

@aspiers aspiers changed the title Support calculating the amount of output TCO2 based on POOL Support calculating the amount of TCO2 redeemed based on POOL Jan 25, 2024
@aspiers
Copy link
Member

aspiers commented Jan 29, 2024

@PawelTroka

One thing to note is that we can't calculate exact amount of POOL that's requested by user, the reason is the method we implement this is by iteratively searching for TCO2 that would yield the closest POOL amount.

Why isn't it possible to calculate this exactly rather than via iteration?

@aspiers
Copy link
Member

aspiers commented Jan 29, 2024

Regarding this:

This issue tracks the missing functionality of calculating the amount of TCO2 received via redemption when providing POOL amount. Which is opposite to what's available rn.

I just wanted to check my understanding here and try to explicitly document what we are talking about for clarity. I think the key points about our current redemption code are as follows:

  1. The fee calculation currently relies on:

    b = (current_asset_volume +/- deposit/redemption amount ) / (total_pool_volume +/- deposit/redemption amount)
    

    where in the redemption case, deposit/redemption amount refers to the amount of TCO2 received by redemption

  2. The fee is taken in POOL, which means that the fee doesn't get redeemed and therefore doesn't affect pool composition.

So with this approach we first need to know the amount of TCO2 received by redemption, then we can calculate the fee, and that gives us the amount of pool the user will spend:

    POOL_to_spend = TCO2_to_receive + redemption_fee(TCO2_before, TCO2_before - TCO2_to_receive, totalTCO2supply)

So the challenge would be to rearrange this equation to solve for TCO2_to_receive given known inputs for POOL_to_spend and TCO2_before, right?

Similarly, with depositing, currently we first need to know the amount of TCO2 the user wants to deposit, and then we can calculate how much POOL they receive via:

    POOL_to_receive = TCO2_to_spend - deposit_fee(TCO2_before, TCO2_before + TCO2_to_spend, totalTCO2supply)

With depositing I guess it's less important to allow the user to choose how much POOL they'll receive and calculate the amount of TCO2 needed for that, but if we wanted to do that, we'd have to solve this equation for TCO2_to_spend given known inputs for POOL_to_receive and TCO2_before.

@aspiers
Copy link
Member

aspiers commented Jan 30, 2024

@PawelTroka

One thing to note is that we can't calculate exact amount of POOL that's requested by user, the reason is the method we implement this is by iteratively searching for TCO2 that would yield the closest POOL amount.

Why isn't it possible to calculate this exactly rather than via iteration?

I think I answered my own question in https://www.notion.so/Redemption-with-CHAR-spend-as-input-c88f4c4c6c7a4b1b814d8ce20681bf31

@aspiers
Copy link
Member

aspiers commented Jan 30, 2024

On top of above, we may need to have this estimation function outside the redeemInMany call due to gas usage. So the flow would be

call estimateTCO2(uint256 poolAmount) returns uint256 -> estimatedTCO2
call redeemInMany(estimatedTCO2, maxPOOLamount, ....)

where maxPOOLamount would check that the result is not exceeding that amount in redeemInMany after making redemption - similarly to slippage protection in uniswap.

If they are done in two separate calls then it loses the value doing the estimation on-chain, which is to estimate and redeem atomically in order to avoid race conditions with other deposits/redeems. This way we can guarantee the exact result requested.

If instead we accept the race conditions and defend with limit parameters like maxPOOLamount like you suggest, then we can do the estimation off-chain in which case it can be way more accurate and we don't have to worry about gas.

Both options seem viable to me, but we need to choose between them. Would love to hear what you guys think about this! Cc @0xmichalis

@kosecki123
Copy link
Contributor Author

@PawelTroka
Copy link
Contributor

@kosecki123
Copy link
Contributor Author

On top of above, we may need to have this estimation function outside the redeemInMany call due to gas usage. So the flow would be

call estimateTCO2(uint256 poolAmount) returns uint256 -> estimatedTCO2

call redeemInMany(estimatedTCO2, maxPOOLamount, ....)

where maxPOOLamount would check that the result is not exceeding that amount in redeemInMany after making redemption - similarly to slippage protection in uniswap.

If they are done in two separate calls then it loses the value doing the estimation on-chain, which is to estimate and redeem atomically in order to avoid race conditions with other deposits/redeems. This way we can guarantee the exact result requested.

If instead we accept the race conditions and defend with limit parameters like maxPOOLamount like you suggest, then we can do the estimation off-chain in which case it can be way more accurate and we don't have to worry about gas.

Both options seem viable to me, but we need to choose between them. Would love to hear what you guys think about this! Cc @0xmichalis

I think regardless we need to have the slippage protection. Basically you need to assume there is MEV in play.

To me the best that covers all is to estimate off-chain and execute on-chain, similarly to AMMs. The diff here is that we cannot have 'exact' amounts as we approximate in case of POOL input.

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

Successfully merging a pull request may close this issue.

3 participants