198 lines
6.2 KiB
Solidity
198 lines
6.2 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity 0.8.19;
|
|
|
|
import { ERC20, SafeTransferLib } from "../lib/utils/SafeTransferLib.sol";
|
|
import { IReputation } from "../lib/interfaces/IReputation.sol";
|
|
import { EventAndErrors } from "./EventAndErrors.sol";
|
|
import { Constants } from "./Constants.sol";
|
|
import { Owned } from "../lib/auth/Owned.sol";
|
|
|
|
abstract contract OwnerSettings is
|
|
Constants,
|
|
EventAndErrors,
|
|
Owned(msg.sender)
|
|
{
|
|
/// ███ Storage ████████████████████████████████████████████████████████████
|
|
|
|
/// @dev List of valid Bacen signature addresses
|
|
/// mapping(uint256 => bool) public validBacenSigners;
|
|
/// @dev Value in custom storage slot given by:
|
|
/// let value := sload(shl(12, address)).
|
|
|
|
IReputation public reputation;
|
|
/// @dev Default blocks that lock will hold tokens.
|
|
uint256 public defaultLockBlocks;
|
|
|
|
/// ███ Constructor ████████████████████████████████████████████████████████
|
|
|
|
constructor(
|
|
uint256 defaultBlocks,
|
|
address[] memory validSigners,
|
|
address _reputation,
|
|
address[] memory tokens,
|
|
bool[] memory tokenStates
|
|
) {
|
|
setDefaultLockBlocks(defaultBlocks);
|
|
setValidSigners(validSigners);
|
|
setReputation(IReputation(_reputation));
|
|
tokenSettings(tokens, tokenStates);
|
|
}
|
|
|
|
/// ███ Owner Only █████████████████████████████████████████████████████████
|
|
|
|
/// @dev Contract's underlying balance withdraw method.
|
|
/// @dev Function sighash: 0x5fd8c710.
|
|
function withdrawBalance() external onlyOwner {
|
|
uint256 balance = address(this).balance;
|
|
SafeTransferLib.safeTransferETH(msg.sender, balance);
|
|
emit FundsWithdrawn(msg.sender, balance);
|
|
}
|
|
|
|
function setReputation(
|
|
IReputation _reputation
|
|
) public onlyOwner {
|
|
assembly {
|
|
sstore(reputation.slot, _reputation)
|
|
}
|
|
emit ReputationUpdated(address(_reputation));
|
|
}
|
|
|
|
function setDefaultLockBlocks(
|
|
uint256 _blocks
|
|
) public onlyOwner {
|
|
assembly {
|
|
sstore(defaultLockBlocks.slot, _blocks)
|
|
}
|
|
emit LockBlocksUpdated(_blocks);
|
|
}
|
|
|
|
function setValidSigners(
|
|
address[] memory _validSigners
|
|
) public onlyOwner {
|
|
assembly {
|
|
let i := add(_validSigners, 0x20)
|
|
let end := add(i, shl(0x05, mload(_validSigners)))
|
|
for {
|
|
/* */
|
|
} iszero(returndatasize()) {
|
|
/* */
|
|
} {
|
|
sstore(shl(12, mload(i)), true)
|
|
i := add(i, 0x20)
|
|
|
|
if iszero(lt(i, end)) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
emit ValidSignersUpdated(_validSigners);
|
|
}
|
|
|
|
function tokenSettings(
|
|
address[] memory _tokens,
|
|
bool[] memory _states
|
|
) public onlyOwner {
|
|
/* Yul Impl */
|
|
assembly {
|
|
// first 32 bytes eq to array's length
|
|
let tLen := mload(_tokens)
|
|
// NoTokens()
|
|
if iszero(tLen) {
|
|
mstore(0x00, 0xdf957883)
|
|
revert(0x1c, 0x04)
|
|
}
|
|
// LengthMismatch()
|
|
if iszero(eq(tLen, mload(_states))) {
|
|
mstore(0x00, 0xff633a38)
|
|
revert(0x1c, 0x04)
|
|
}
|
|
let tLoc := add(_tokens, 0x20)
|
|
let sLoc := add(_states, 0x20)
|
|
for {
|
|
let end := add(tLoc, shl(5, tLen))
|
|
} iszero(eq(tLoc, end)) {
|
|
tLoc := add(tLoc, 0x20)
|
|
sLoc := add(sLoc, 0x20)
|
|
} {
|
|
// cache hashmap entry in scratch space
|
|
mstore(0x0c, _ALLOWED_ERC20_SLOT_SEED)
|
|
mstore(0x00, mload(tLoc))
|
|
// let mapSlot := keccak256(0x0c, 0x20)
|
|
sstore(keccak256(0x0c, 0x20), mload(sLoc))
|
|
|
|
// emit AllowedERC20Updated(address, bool)
|
|
log3(
|
|
0,
|
|
0,
|
|
_ALLOWED_ERC20_UPDATED_EVENT_SIGNATURE,
|
|
mload(tLoc),
|
|
mload(sLoc)
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
/// ███ View FX ████████████████████████████████████████████████████████████
|
|
|
|
function validBacenSigners(
|
|
uint256 signer
|
|
) public view returns (bool valid) {
|
|
assembly {
|
|
valid := sload(signer)
|
|
}
|
|
}
|
|
|
|
function sellerAllowList(
|
|
uint256 sellerKey
|
|
) public view returns (bytes32 root) {
|
|
assembly {
|
|
mstore(0x0c, _SELLER_ALLOWLIST_SLOT_SEED)
|
|
mstore(0x00, shr(12, sellerKey))
|
|
root := sload(keccak256(0x00, 0x20))
|
|
}
|
|
}
|
|
|
|
function allowedERC20s(
|
|
ERC20 erc20
|
|
) public view returns (bool state) {
|
|
assembly {
|
|
mstore(0x0c, _ALLOWED_ERC20_SLOT_SEED)
|
|
mstore(0x00, erc20)
|
|
state := sload(keccak256(0x0c, 0x20))
|
|
}
|
|
}
|
|
|
|
function _limiter(
|
|
uint256 _userCredit
|
|
) internal view returns (uint256 _spendLimit) {
|
|
bytes memory encodedParams = abi.encodeWithSelector(
|
|
// IReputation.limiter.selector,
|
|
0x4d2b1791,
|
|
_userCredit
|
|
);
|
|
bool success;
|
|
assembly {
|
|
success := staticcall(
|
|
// gas
|
|
0x7530,
|
|
// address
|
|
sload(reputation.slot),
|
|
// argsOffset
|
|
add(encodedParams, 0x20),
|
|
// argsSize
|
|
mload(encodedParams),
|
|
// retOffset
|
|
0x00,
|
|
// retSize
|
|
0x20
|
|
)
|
|
_spendLimit := mload(0x00)
|
|
if iszero(success) {
|
|
// StaticCallFailed()
|
|
mstore(0x00, 0xe10bf1cc)
|
|
revert(0x1c, 0x04)
|
|
}
|
|
}
|
|
}
|
|
}
|