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

Meta Calculator: implementation of bulk get_dy and get_dx #15

Open
wants to merge 13 commits into
base: meta-calc
Choose a base branch
from

Conversation

samwerner
Copy link
Contributor

Feature

This PR adds full functionality for the meta pool calculator.

The following was implemented:

  • Fix small bugs in bulk get_dy (only in meta calc; these weren't tested before)
  • Add tests for bulk get_dy for meta calculator
  • Add bulk get_dx in meta calculator
  • Add tests for bulk get_dx for meta calculator

Tests

The added tests for the meta calculator can be found in: tests/local/unitary/Swaps/test_calculator_meta.py

For both, get_dy() and get_dx() of the meta calculator, tests were added for:

  • Base pool token - Base pool token swaps
  • Base pool token - Meta pool token swaps
  • Meta pool token - Meta LP token swaps
  • Meta pool token - Base pool token swaps
  • Unsupported pool sizes (raise)

Note: There are two tests disabled. In get_dx(), there is some calculation error regarding the base pool fees, which results in small differences between the expected and actual outputs. This issue can be reproduced by uncommenting the pytest decorators @pytest.mark.skip().

If the base pool fee is set to 0, via swap._set_fee(0) in the two tests, the expected and actual results in the tests are fine, apart from small floating-point differences.

The base fee computation bug is within the logic for when dx is the meta pool token and dy a base pool token (block starting at line 411 in CurveCalcMeta.vy) and for when dx is a base pool token and dy the meta pool token (block starting at line 392 in CurveCalcMeta.vy).

@@ -39,7 +39,7 @@ interface CurveBase:


MAX_COINS: constant(int128) = 8
INPUT_SIZE: constant(int128) = 100
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed INPUT_SIZE to 80 as the contract size was exceeding the bytecode size limit. Was there a particular reason for setting it to 100?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some number. Doesn't matter how big it is I think as long as it fits, but should be big enough. That's for DEX aggregators to do this on-chain (where INPUT_SIZE is the maximum they do)

@@ -18,7 +18,7 @@ symbol: public(String[32])
decimals: public(uint256)
balanceOf: public(HashMap[address, uint256])
allowances: HashMap[address, HashMap[address, uint256]]
total_supply: uint256
total_supply: public(uint256)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You actually don't need this public because totalSupply is already public

@external
@view
def A_precise() -> uint256:
return self.A
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, in real pools A_precise is larger than A by a multiplier A_PRECISION = 100

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.

2 participants