optimize uq104 to avoid higher bit space math
This commit is contained in:
@ -88,8 +88,8 @@ contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0), SafeTran
|
||||
uint128 blocksElapsed = (block.number - blockNumberLast).downcast128();
|
||||
|
||||
// get the prices according to the reserves as of the last official interaction with the contract
|
||||
uint208 priceToken0 = UQ104x104.encode(reserves.token0).qdiv(UQ104x104.encode(reserves.token1));
|
||||
uint208 priceToken1 = UQ104x104.encode(reserves.token1).qdiv(UQ104x104.encode(reserves.token0));
|
||||
uint208 priceToken0 = UQ104x104.encode(reserves.token0).qdiv(reserves.token1);
|
||||
uint208 priceToken1 = UQ104x104.encode(reserves.token1).qdiv(reserves.token0);
|
||||
|
||||
return (
|
||||
priceToken0Accumulated + (uint240(priceToken0) * blocksElapsed),
|
||||
@ -126,8 +126,8 @@ contract UniswapV2 is IUniswapV2, ERC20("Uniswap V2", "UNI-V2", 18, 0), SafeTran
|
||||
uint32 blocksElapsed = blockNumber - blockNumberLast;
|
||||
|
||||
// get the prices according to the reserves as of the last official interaction with the contract
|
||||
uint208 priceToken0 = UQ104x104.encode(reserves.token0).qdiv(UQ104x104.encode(reserves.token1));
|
||||
uint208 priceToken1 = UQ104x104.encode(reserves.token1).qdiv(UQ104x104.encode(reserves.token0));
|
||||
uint208 priceToken0 = UQ104x104.encode(reserves.token0).qdiv(reserves.token1);
|
||||
uint208 priceToken1 = UQ104x104.encode(reserves.token1).qdiv(reserves.token0);
|
||||
|
||||
// multiply these prices by the number of elapsed blocks and add to the accumulators
|
||||
priceToken0Accumulated = priceToken0Accumulated + (uint240(priceToken0) * blocksElapsed);
|
||||
|
||||
@ -17,14 +17,18 @@ library UQ104x104 {
|
||||
return uint232(y) * Q104;
|
||||
}
|
||||
|
||||
// we want to divide two modified-UQ104.104s (the outputs of encode), and return a traditional Q104.
|
||||
// for our purposes, we'll do that by flooring the output of the division with `uint208(-1)`.
|
||||
// (this corresponds to capping the relative prices of x and y at `1 / 2**104` and `uint208(-1) / 2**104`.)
|
||||
// unfortunately, before we can compute `min(uint208(-1), output), we need to compute `output = x * 2**104 / y`,
|
||||
// for which we need at least 416 bits (possibly 438 or 464? TODO think this through).
|
||||
// for now, we just mock the function
|
||||
function qdiv(uint232 x, uint232 y) internal pure returns (uint208 z) {
|
||||
// TODO replace mock with real logic
|
||||
z = uint208(x * Q104 / y);
|
||||
// we want to divide a modified UQ104.104 (the output of encode) by an unencoded uint128,
|
||||
// and return a traditional Q104. since we're using a modified UQ104.104, though, we need to handle overflows.
|
||||
// for the moment, we simply truncate these to 1 and uint208(-1), though it's likely we'll handle this slightly
|
||||
// differently in the future
|
||||
function qdiv(uint232 x, uint128 y) internal pure returns (uint208 z) {
|
||||
uint232 temp = x / y;
|
||||
if (temp == 0) {
|
||||
z = 1;
|
||||
} else if (temp > uint208(-1)) {
|
||||
z = uint208(-1);
|
||||
} else {
|
||||
z = uint208(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user