buttonwood-protocol / button-wrappers

Solidity code for the ButtonToken rebasing wrapper protocol
GNU General Public License v3.0
13 stars 10 forks source link

Button Token implementation #7

Closed aalavandhan closed 3 years ago

aalavandhan commented 3 years ago

Button token implementation with unit and precision tests

aalavandhan commented 3 years ago

The SRD impl is broken as it doesn’t guarantee numeric stability for transfers. eg) A->B calls transfer with 10 tokens but only 9.99999999 tokens get transferred. This will break all downstream apps 😕

For AMPL we derived the numeric value for the internal representation “gons” such that as long as supply is less than the MAX_SUPPLY transfers will always be precise.

For the button token I played around with a few implementations, but I’ve finally landed on the current version which I think is the simplest and most accurate.

In this case TotalSupply = (collateralBalance * price); if we enforce a MAX_COLLATERAL we can calculate the MAX_PRICE such that transfers will always be precise.

The current implementation pre-mines MAX_COLLATERAL worth of “shares” (or gons) and assigns it to “address(0)“. On mint and burn it just transfers from and back from there.

For both BTC and ETH we can safely set MAX_COLLATERAL as we know their supply schedule.

marktoda commented 3 years ago

Precision test failing sometimes - is it flaky?

  1) Precision tests
       should successfully run simulation:
     Error: VM Exception while processing transaction: revert ERC20: transfer amount exceeds allowance
      at ButtonToken._verifyCallResult (@openzeppelin/contracts/utils/Address.sol:182)
      at ButtonToken.functionCallWithValue (@openzeppelin/contracts/utils/Address.sol:120)
      at ButtonToken.functionCall (@openzeppelin/contracts/utils/Address.sol:90)
      at ButtonToken._callOptionalReturn (@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol:71)
      at ButtonToken.safeTransfer (@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol:21)
      at ButtonToken.mint (contracts/ButtonToken.sol:471)
      at process._tickCallback (internal/process/next_tick.js:68:7)
aalavandhan commented 3 years ago

Precision test failing sometimes - is it flaky?

  1) Precision tests
       should successfully run simulation:
     Error: VM Exception while processing transaction: revert ERC20: transfer amount exceeds allowance
      at ButtonToken._verifyCallResult (@openzeppelin/contracts/utils/Address.sol:182)
      at ButtonToken.functionCallWithValue (@openzeppelin/contracts/utils/Address.sol:120)
      at ButtonToken.functionCall (@openzeppelin/contracts/utils/Address.sol:90)
      at ButtonToken._callOptionalReturn (@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol:71)
      at ButtonToken.safeTransfer (@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol:21)
      at ButtonToken.mint (contracts/ButtonToken.sol:471)
      at process._tickCallback (internal/process/next_tick.js:68:7)

I've opened an issue for this will fix it separately