Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explicit storage slot to keep KycProvidersManager #57

Merged
merged 2 commits into from
Feb 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions src/zkbob/utils/KycProvidersManagerStorage.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// SPDX-License-Identifier: CC0-1.0

pragma solidity 0.8.15;

import "@openzeppelin/contracts/utils/Address.sol";
import "../../interfaces/IKycProvidersManager.sol";
import "../../utils/Ownable.sol";

contract KycProvidersManagerStorage is Ownable {
// In order to avoid shifting storage slots by defining a new variable in
// the contract, KYC Providers Manager will be accessed through specifying
// a free slot explicitly. Similar approach is used in EIP1967.
//
// bytes32(uint256(keccak256('zkBob.ZkBobAccounting.kycProvidersManager')) - 1)
uint256 internal constant KYC_PROVIDER_MANAGER_STORAGE =
0x06c991646992b7f0f3fd0c832eac3f519e26682bcb82fbbcfd1ff8013d876f64;

event UpdateKYCProvidersManager(address manager);

/**
* @dev Tells the KYC Providers Manager contract address.
* @return res the manager address.
*/
function kycProvidersManager() public view returns (IKycProvidersManager res) {
assembly {
res := sload(KYC_PROVIDER_MANAGER_STORAGE)
}
}

/**
* @dev Updates kyc providers manager contract.
* Callable only by the contract owner / proxy admin.
* @param _kycProvidersManager new operator manager implementation.
*/
function setKycProvidersManager(IKycProvidersManager _kycProvidersManager) external onlyOwner {
require(Address.isContract(address(_kycProvidersManager)), "KycProvidersManagerStorage: not a contract");
assembly {
sstore(KYC_PROVIDER_MANAGER_STORAGE, _kycProvidersManager)
}
emit UpdateKYCProvidersManager(address(_kycProvidersManager));
}
}
23 changes: 5 additions & 18 deletions src/zkbob/utils/ZkBobAccounting.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
pragma solidity 0.8.15;

import "../../interfaces/IKycProvidersManager.sol";
import "../../utils/Ownable.sol";
import "./KycProvidersManagerStorage.sol";

/**
* @title ZkBobAccounting
Expand All @@ -12,7 +12,7 @@ import "../../utils/Ownable.sol";
* Limitations: Contract will only work correctly as long as pool tvl does not exceed 4.7e12 BOB (4.7 trillion)
* and overall transaction count does not exceed 4.3e9 (4.3 billion). Pool usage limits cannot exceed 4.3e9 BOB (4.3 billion) per day.
*/
contract ZkBobAccounting is Ownable {
contract ZkBobAccounting is KycProvidersManagerStorage {
uint256 internal constant PRECISION = 1_000_000_000;
uint256 internal constant SLOT_DURATION = 1 hours;
uint256 internal constant DAY_SLOTS = 1 days / SLOT_DURATION;
Expand Down Expand Up @@ -115,11 +115,8 @@ contract ZkBobAccounting is Ownable {
mapping(uint256 => Snapshot) private snapshots; // single linked list of hourly snapshots
mapping(address => UserStats) private userStats;

IKycProvidersManager public kycProvidersManager;

event UpdateLimits(uint8 indexed tier, TierLimits limits);
event UpdateTier(address user, uint8 tier);
event UpdateKYCProvidersManager(address manager);

/**
* @dev Returns currently configured limits and remaining quotas for the given user as of the current block.
Expand Down Expand Up @@ -152,17 +149,6 @@ contract ZkBobAccounting is Ownable {
});
}

/**
* @dev Updates kyc providers manager contract.
* Callable only by the contract owner / proxy admin.
* @param _kycProvidersManager new operator manager implementation.
*/
function setKycProvidersManager(IKycProvidersManager _kycProvidersManager) external onlyOwner {
require(address(_kycProvidersManager) != address(0), "ZkBobPool: manager is zero address");
kycProvidersManager = _kycProvidersManager;
emit UpdateKYCProvidersManager(address(_kycProvidersManager));
}

function _recordOperation(
address _user,
int256 _txAmount
Expand Down Expand Up @@ -348,8 +334,9 @@ contract ZkBobAccounting is Ownable {
// Tier is set as per the KYC Providers Manager recomendation only in the case if no
// specific tier assigned to the user
function _adjustConfiguredTierForUser(address _user, uint8 _configuredTier) internal view returns (uint8) {
if (_configuredTier == 0 && address(kycProvidersManager) != address(0)) {
(bool kycPassed, uint8 tier) = kycProvidersManager.getIfKYCpassedAndTier(_user);
IKycProvidersManager kycProvidersMgr = kycProvidersManager();
if (_configuredTier == 0 && address(kycProvidersMgr) != address(0)) {
(bool kycPassed, uint8 tier) = kycProvidersMgr.getIfKYCpassedAndTier(_user);
if (kycPassed && tiers[tier].limits.tvlCap > 0) {
return tier;
}
Expand Down
2 changes: 1 addition & 1 deletion test/zkbob/utils/ZkBobAccounting.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ contract ZkBobAccountingTest is Test {
address manager = address(_setKYCPorviderManager());
assertEq(address(pool.kycProvidersManager()), manager);

vm.expectRevert("ZkBobPool: manager is zero address");
vm.expectRevert("KycProvidersManagerStorage: not a contract");
pool.setKycProvidersManager(SimpleKYCProviderManager(address(0)));
}

Expand Down