81 lines
2.7 KiB
Solidity
81 lines
2.7 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity 0.8.9;
|
|
|
|
import { IReputation } from "./lib/interfaces/IReputation.sol";
|
|
import { Owned } from "./lib/auth/Owned.sol";
|
|
|
|
contract Reputation is IReputation, Owned(msg.sender) {
|
|
/// @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(/* */) {/* */}
|
|
|
|
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))
|
|
}
|
|
}
|
|
}
|