Had a discussion with @dagurval about overflows and overflow-workarounds for Caldron Dex.
Cauldron uses x * y = k
to calculate the target constant “k” for the pool to check the "effective k " after a user interaction. This overflows on maxint32 * maxint32
which means a pool can hold at a maximum ~2.1 billion sats (21BCH) and ~2.1 billion tokens.
To work around this limit, the most expedient solution for now would be to use (x/c) * (y/c) = k
where “c” is a division constant chosen by the pool operator. This sacrifices on precision of the multiplication, take the following example:
An AMM pool holds 888,888 satoshis and 888,888 tokens. If for the design the pool, the “k” should not overflow 1 billion , we can use c=1000
.
The pool constant k would be calculated by k = (888,888 / 1000) * (888,888 / 1000)
=> k = 888 * 888
so k = 788,544
or when rounding up after each division k = 889 * 889 = 790,321
The calculation loses precision because the truncation with the division happens before the multiplication.
With a muldiv opcode, which only does the division at the end, the calculation would be
k = muldiv(888,888 ; 888,888 ; 1,000,000) = 790,121
so only truncation after the multiplication.
Another option with op_muldiv
& op_mulmod
would be to emulate int127 multiplication and the int127 inequaltiy check if full precision is necessary.