|
| 1 | +// SPDX-License-Identifier: Apache-2.0 |
| 2 | +// Copyright 2024 Aztec Labs. |
| 3 | +pragma solidity >=0.8.27; |
| 4 | + |
| 5 | +import {Math} from "@oz/utils/math/Math.sol"; |
| 6 | +import {SafeCast} from "@oz/utils/math/SafeCast.sol"; |
| 7 | +import {SignedMath} from "@oz/utils/math/SignedMath.sol"; |
| 8 | + |
| 9 | +import {Errors} from "./Errors.sol"; |
| 10 | + |
| 11 | +struct OracleInput { |
| 12 | + int256 provingCostModifier; |
| 13 | + int256 feeAssetPriceModifier; |
| 14 | +} |
| 15 | + |
| 16 | +library FeeMath { |
| 17 | + using Math for uint256; |
| 18 | + using SafeCast for int256; |
| 19 | + using SafeCast for uint256; |
| 20 | + using SignedMath for int256; |
| 21 | + |
| 22 | + // These values are taken from the model, but mostly pulled out of the ass |
| 23 | + uint256 internal constant MINIMUM_PROVING_COST_PER_MANA = 5415357955; |
| 24 | + uint256 internal constant MAX_PROVING_COST_MODIFIER = 1000000000; |
| 25 | + uint256 internal constant PROVING_UPDATE_FRACTION = 100000000000; |
| 26 | + |
| 27 | + uint256 internal constant MINIMUM_FEE_ASSET_PRICE = 10000000000; |
| 28 | + uint256 internal constant MAX_FEE_ASSET_PRICE_MODIFIER = 1000000000; |
| 29 | + uint256 internal constant FEE_ASSET_PRICE_UPDATE_FRACTION = 100000000000; |
| 30 | + |
| 31 | + function assertValid(OracleInput memory _self) internal pure returns (bool) { |
| 32 | + require( |
| 33 | + SignedMath.abs(_self.provingCostModifier) <= MAX_PROVING_COST_MODIFIER, |
| 34 | + Errors.FeeMath__InvalidProvingCostModifier() |
| 35 | + ); |
| 36 | + require( |
| 37 | + SignedMath.abs(_self.feeAssetPriceModifier) <= MAX_FEE_ASSET_PRICE_MODIFIER, |
| 38 | + Errors.FeeMath__InvalidFeeAssetPriceModifier() |
| 39 | + ); |
| 40 | + return true; |
| 41 | + } |
| 42 | + |
| 43 | + function clampedAdd(uint256 _a, int256 _b) internal pure returns (uint256) { |
| 44 | + if (_b >= 0) { |
| 45 | + return _a + _b.toUint256(); |
| 46 | + } |
| 47 | + |
| 48 | + uint256 sub = SignedMath.abs(_b); |
| 49 | + |
| 50 | + if (_a > sub) { |
| 51 | + return _a - sub; |
| 52 | + } |
| 53 | + |
| 54 | + return 0; |
| 55 | + } |
| 56 | + |
| 57 | + function provingCostPerMana(uint256 _numerator) internal pure returns (uint256) { |
| 58 | + return fakeExponential(MINIMUM_PROVING_COST_PER_MANA, _numerator, PROVING_UPDATE_FRACTION); |
| 59 | + } |
| 60 | + |
| 61 | + function feeAssetPriceModifier(uint256 _numerator) internal pure returns (uint256) { |
| 62 | + return fakeExponential(MINIMUM_FEE_ASSET_PRICE, _numerator, FEE_ASSET_PRICE_UPDATE_FRACTION); |
| 63 | + } |
| 64 | + |
| 65 | + function fakeExponential(uint256 _factor, uint256 _numerator, uint256 _denominator) |
| 66 | + private |
| 67 | + pure |
| 68 | + returns (uint256) |
| 69 | + { |
| 70 | + uint256 i = 1; |
| 71 | + uint256 output = 0; |
| 72 | + uint256 numeratorAccumulator = _factor * _denominator; |
| 73 | + while (numeratorAccumulator > 0) { |
| 74 | + output += numeratorAccumulator; |
| 75 | + numeratorAccumulator = (numeratorAccumulator * _numerator) / (_denominator * i); |
| 76 | + i += 1; |
| 77 | + } |
| 78 | + return output / _denominator; |
| 79 | + } |
| 80 | +} |
0 commit comments