// SPDX-License-Identifier: MIT pragma solidity 0.8.19; import { IReputation } from "./lib/interfaces/IReputation.sol"; contract Reputation is IReputation { /// @dev Asymptote numerator constant value for the `limiter` fx. uint256 public constant maxLimit = 1e6; /// @dev Denominator's constant operand for the `limiter` fx. uint256 public constant magicValue = 2.5e11; // prettier-ignore // solhint-disable no-inline-assembly // solhint-disable-next-line no-empty-blocks constructor(/* */) payable {/* */} function limiter( uint256 _userCredit ) external pure override(IReputation) returns (uint256 _spendLimit) { _spendLimit = (1 + ((maxLimit * _userCredit) / sqrt( magicValue + (_userCredit * _userCredit) ))); } /// @notice Taken from Solmate's FixedPointMathLib. /// (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol) function sqrt( uint256 x ) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { let y := x // We start y at x, which will help us make our initial estimate. z := 181 // The "correct" value is 1, but this saves a multiplication later. // We check y >= 2^(k + 8) but shift right by k bits // each branch to ensure that if x >= 256, then y >= 256. if iszero( lt(y, 0x10000000000000000000000000000000000) ) { y := shr(128, y) z := shl(64, z) } if iszero(lt(y, 0x1000000000000000000)) { y := shr(64, y) z := shl(32, z) } if iszero(lt(y, 0x10000000000)) { y := shr(32, y) z := shl(16, z) } if iszero(lt(y, 0x1000000)) { y := shr(16, y) z := shl(8, z) } // There is no overflow risk here since y < 2^136 after the first branch above. z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181. // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough. z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := sub(z, lt(div(x, z), z)) } } }