编译器
0.8.14+commit.80d49f37
文件 1 的 23:AccessControl.sol
pragma solidity ^0.8.0;
import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address => bool) members;
bytes32 adminRole;
}
mapping(bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
return _roles[role].members[account];
}
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
Strings.toHexString(account),
" is missing role ",
Strings.toHexString(uint256(role), 32)
)
)
);
}
}
function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
return _roles[role].adminRole;
}
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
function renounceRole(bytes32 role, address account) public virtual override {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
}
文件 2 的 23:AddressSet.sol
pragma solidity 0.8.14;
library AddressSet {
struct Set {
mapping(address => uint256) keyPointers;
address[] keyList;
}
string private constant MODULE = "AddressSet";
error AddressSetConsistency(string module, string method, string reason, string context);
function insert(
Set storage self,
address key,
string memory context
) internal {
if (exists(self, key))
revert AddressSetConsistency({
module: MODULE,
method: "insert",
reason: "exists",
context: context
});
self.keyList.push(key);
self.keyPointers[key] = self.keyList.length - 1;
}
function remove(
Set storage self,
address key,
string memory context
) internal {
if (!exists(self, key))
revert AddressSetConsistency({
module: MODULE,
method: "remove",
reason: "does not exist",
context: context
});
address keyToMove = self.keyList[count(self) - 1];
uint256 rowToReplace = self.keyPointers[key];
self.keyPointers[keyToMove] = rowToReplace;
self.keyList[rowToReplace] = keyToMove;
delete self.keyPointers[key];
self.keyList.pop();
}
function count(Set storage self) internal view returns (uint256) {
return (self.keyList.length);
}
function exists(Set storage self, address key) internal view returns (bool) {
if (self.keyList.length == 0) return false;
return self.keyList[self.keyPointers[key]] == key;
}
function keyAtIndex(Set storage self, uint256 index) internal view returns (address) {
return self.keyList[index];
}
}
文件 3 的 23:Bytes32Set.sol
pragma solidity 0.8.14;
library Bytes32Set {
struct Set {
mapping(bytes32 => uint256) keyPointers;
bytes32[] keyList;
}
string private constant MODULE = "Bytes32Set";
error Bytes32SetConsistency(string module, string method, string reason, string context);
function insert(
Set storage self,
bytes32 key,
string memory context
) internal {
if (exists(self, key))
revert Bytes32SetConsistency({
module: MODULE,
method: "insert",
reason: "exists",
context: context
});
self.keyPointers[key] = self.keyList.length;
self.keyList.push(key);
}
function remove(
Set storage self,
bytes32 key,
string memory context
) internal {
if (!exists(self, key))
revert Bytes32SetConsistency({
module: MODULE,
method: "remove",
reason: "does not exist",
context: context
});
bytes32 keyToMove = self.keyList[count(self) - 1];
uint256 rowToReplace = self.keyPointers[key];
self.keyPointers[keyToMove] = rowToReplace;
self.keyList[rowToReplace] = keyToMove;
delete self.keyPointers[key];
self.keyList.pop();
}
function count(Set storage self) internal view returns (uint256) {
return (self.keyList.length);
}
function exists(Set storage self, bytes32 key) internal view returns (bool) {
if (self.keyList.length == 0) return false;
return self.keyList[self.keyPointers[key]] == key;
}
function keyAtIndex(Set storage self, uint256 index) internal view returns (bytes32) {
return self.keyList[index];
}
}
文件 4 的 23:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 5 的 23:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 6 的 23:ERC2771Context.sol
pragma solidity ^0.8.9;
import "../utils/Context.sol";
abstract contract ERC2771Context is Context {
address private immutable _trustedForwarder;
constructor(address trustedForwarder) {
_trustedForwarder = trustedForwarder;
}
function isTrustedForwarder(address forwarder) public view virtual returns (bool) {
return forwarder == _trustedForwarder;
}
function _msgSender() internal view virtual override returns (address sender) {
if (isTrustedForwarder(msg.sender)) {
assembly {
sender := shr(96, calldataload(sub(calldatasize(), 20)))
}
} else {
return super._msgSender();
}
}
function _msgData() internal view virtual override returns (bytes calldata) {
if (isTrustedForwarder(msg.sender)) {
return msg.data[:msg.data.length - 20];
} else {
return super._msgData();
}
}
}
文件 7 的 23:IAccessControl.sol
pragma solidity ^0.8.0;
interface IAccessControl {
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
function hasRole(bytes32 role, address account) external view returns (bool);
function getRoleAdmin(bytes32 role) external view returns (bytes32);
function grantRole(bytes32 role, address account) external;
function revokeRole(bytes32 role, address account) external;
function renounceRole(bytes32 role, address account) external;
}
文件 8 的 23:IDegradable.sol
pragma solidity 0.8.14;
interface IDegradable {
event SetPolicyParameters(
address indexed admin,
uint32 indexed policyId,
uint256 degradationPeriod,
uint256 degradationFreshness);
struct MitigationParameters {
uint256 degradationPeriod;
uint256 degradationFreshness;
}
function ROLE_SERVICE_SUPERVISOR() external view returns (bytes32);
function defaultDegradationPeriod() external view returns (uint256);
function defaultFreshnessPeriod() external view returns (uint256);
function policyManager() external view returns (address);
function lastUpdate() external view returns (uint256);
function subjectUpdates(bytes32 subject) external view returns (uint256 timestamp);
function setPolicyParameters(
uint32 policyId,
uint256 degradationPeriod,
uint256 degradationFreshness
) external;
function canMitigate(
address observer,
bytes32 subject,
uint32 policyId
) external view returns (bool canIndeed) ;
function isDegraded(uint32 policyId) external view returns (bool isIndeed);
function isMitigationQualified(
bytes32 subject,
uint32 policyId
) external view returns (bool qualifies);
function degradationPeriod(uint32 policyId) external view returns (uint256 inSeconds);
function degradationFreshness(uint32 policyId) external view returns (uint256 inSeconds);
function mitigationCutoff(uint32 policyId) external view returns (uint256 cutoffTime);
}
文件 9 的 23:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 10 的 23:IIdentityTree.sol
pragma solidity 0.8.14;
interface IIdentityTree {
event Deployed(
address admin,
address trustedForwarder_,
address policyManager_,
uint256 maximumConsentPeriod);
event SetMerkleRootBirthday(bytes32 merkleRoot, uint256 birthday);
struct PolicyMitigation {
uint256 mitigationFreshness;
uint256 degradationPeriod;
}
function ROLE_AGGREGATOR() external view returns (bytes32);
function setMerkleRootBirthday(bytes32 root, uint256 birthday) external;
function checkRoot(
address observer,
bytes32 merkleRoot,
uint32 admissionPolicyId
) external returns (bool passed);
function merkleRootCount() external view returns (uint256 count);
function merkleRootAtIndex(uint256 index) external view returns (bytes32 merkleRoot);
function isMerkleRoot(bytes32 merkleRoot) external view returns (bool isIndeed);
function latestRoot() external view returns (bytes32 root);
}
文件 11 的 23:IKeyringCredentials.sol
pragma solidity 0.8.14;
interface IKeyringCredentials {
event CredentialsDeployed(
address deployer,
address trustedForwarder,
address policyManager,
uint256 maximumConsentPeriod);
event CredentialsInitialized(address admin);
event UpdateCredential(
uint8 version,
address updater,
address indexed trader,
uint32 indexed admissionPolicyId);
function ROLE_CREDENTIAL_UPDATER() external view returns (bytes32);
function init() external;
function setCredential(
address trader,
uint32 admissionPolicyId,
uint256 timestamp
) external;
function checkCredential(
address observer,
address subject,
uint32 admissionPolicyId
) external returns (bool passed);
function keyGen(
address trader,
uint32 admissionPolicyId
) external pure returns (bytes32 key);
}
文件 12 的 23:IKeyringZkCredentialUpdater.sol
pragma solidity 0.8.14;
import "./IKeyringZkVerifier.sol";
interface IKeyringZkCredentialUpdater {
event CredentialUpdaterDeployed(
address deployer,
address trustedForwarder,
address keyringCache,
address admissionPolicyManager,
address keyringZkVerifier
);
event AdmitIdentityTree(address admin, address identityTree);
event RemoveIdentityTree(address admin, address identityTree);
event AcceptCredentialUpdate(
address sender,
address trader,
IKeyringZkVerifier.IdentityMembershipProof membershipProof,
IKeyringZkVerifier.IdentityAuthorisationProof authorizationProof,
uint256 rootTime);
function POLICY_MANAGER() external view returns (address);
function KEYRING_CREDENTIALS() external view returns (address);
function KEYRING_ZK_VERIFIER() external view returns (address);
function updateCredentials(
address attestor,
IKeyringZkVerifier.IdentityMembershipProof calldata membershipProof,
IKeyringZkVerifier.IdentityAuthorisationProof calldata authorizationProof
) external;
function checkPolicy(
uint32 policyId,
address attestor
) external returns (bool acceptable);
function pack12x20(uint32[12] calldata input) external pure returns (uint256 packed);
function unpack12x20(uint256 packed) external pure returns (uint32[12] memory unpacked);
}
文件 13 的 23:IKeyringZkVerifier.sol
pragma solidity 0.8.14;
interface IKeyringZkVerifier {
error Unacceptable(string reason);
event Deployed(
address deployer,
address identityConstructionProofVerifier,
address membershipProofVerifier,
address authorisationProofVerifier
);
struct Backdoor {
uint256[2] c1;
uint256[2] c2;
}
struct Groth16Proof {
uint256[2] a;
uint256[2][2] b;
uint256[2] c;
}
struct IdentityConstructionProof {
Groth16Proof proof;
uint256[71] inputs;
}
struct IdentityMembershipProof {
Groth16Proof proof;
uint256 root;
uint256 nullifierHash;
uint256 signalHash;
uint256 externalNullifier;
}
struct IdentityAuthorisationProof {
Groth16Proof proof;
Backdoor backdoor;
uint256 externalNullifier;
uint256 nullifierHash;
uint256[2] policyDisclosures;
uint256 tradingAddress;
uint256[2] regimeKey;
}
function IDENTITY_MEMBERSHIP_PROOF_VERIFIER() external returns (address);
function IDENTITY_CONSTRUCTION_PROOF_VERIFIER() external returns (address);
function AUTHORIZATION_PROOF_VERIFIER() external returns (address);
function checkClaim(
IdentityMembershipProof calldata membershipProof,
IdentityAuthorisationProof calldata authorisationProof
) external view returns (bool verified);
function checkIdentityConstructionProof(
IdentityConstructionProof calldata constructionProof
) external view returns (bool verified);
function checkIdentityMembershipProof(
IdentityMembershipProof calldata membershipProof
) external view returns (bool verified);
function checkIdentityAuthorisationProof(
IdentityAuthorisationProof calldata authorisationProof
) external view returns (bool verified);
}
文件 14 的 23:IPolicyManager.sol
pragma solidity 0.8.14;
import "../lib/PolicyStorage.sol";
interface IPolicyManager {
event PolicyManagerDeployed(
address deployer,
address trustedForwarder,
address ruleRegistry);
event PolicyManagerInitialized(address admin);
event CreatePolicy(
address indexed owner,
uint32 indexed policyId,
PolicyStorage.PolicyScalar policyScalar,
address[] attestors,
address[] walletChecks,
bytes32 policyOwnerRole,
bytes32 policyUserAdminRole
);
event DisablePolicy(address user, uint32 policyId);
event UpdatePolicyScalar(
address indexed owner,
uint32 indexed policyId,
PolicyStorage.PolicyScalar policyScalar,
uint256 deadline);
event UpdatePolicyDescription(address indexed owner, uint32 indexed policyId, string description, uint256 deadline);
event UpdatePolicyRuleId(address indexed owner, uint32 indexed policyId, bytes32 indexed ruleId, uint256 deadline);
event UpdatePolicyTtl(address indexed owner, uint32 indexed policyId, uint128 ttl, uint256 deadline);
event UpdatePolicyGracePeriod(
address indexed owner,
uint32 indexed policyId,
uint128 gracePeriod,
uint256 deadline);
event UpdatePolicyLock(address indexed owner, uint32 indexed policyId, bool locked, uint256 deadline);
event UpdatePolicyAllowApprovedCounterparties(
address indexed owner,
uint32 indexed policyId,
bool allowApprovedCounterparties,
uint256 deadline);
event UpdatePolicyDisablementPeriod(
address indexed admin,
uint32 indexed policyId,
uint256 disablementPeriod,
uint256 deadline
);
event PolicyDisabled(address indexed sender, uint32 indexed policyId);
event UpdatePolicyDeadline(address indexed owner, uint32 indexed policyId, uint256 deadline);
event AddPolicyAttestors(
address indexed owner,
uint32 indexed policyId,
address[] attestors,
uint256 deadline
);
event RemovePolicyAttestors(
address indexed owner,
uint32 indexed policyId,
address[] attestor,
uint256 deadline
);
event AddPolicyWalletChecks(
address indexed owner,
uint32 indexed policyId,
address[] walletChecks,
uint256 deadline
);
event RemovePolicyWalletChecks(
address indexed owner,
uint32 indexed policyId,
address[] walletChecks,
uint256 deadline
);
event AddPolicyBackdoor(
address indexed owner,
uint32 indexed policyId,
bytes32 backdoorId,
uint256 deadline
);
event RemovePolicyBackdoor(
address indexed owner,
uint32 indexed policyId,
bytes32 backdoorId,
uint256 deadline
);
event AdmitAttestor(address indexed admin, address indexed attestor, string uri);
event UpdateAttestorUri(address indexed admin, address indexed attestor, string uri);
event RemoveAttestor(address indexed admin, address indexed attestor);
event AdmitWalletCheck(address indexed admin, address indexed walletCheck);
event RemoveWalletCheck(address indexed admin, address indexed walletCheck);
event AdmitBackdoor(address indexed admin, bytes32 id, uint256[2] pubKey);
event MinimumPolicyDisablementPeriodUpdated(uint256 newPeriod);
function ROLE_POLICY_CREATOR() external view returns (bytes32);
function ROLE_GLOBAL_ATTESTOR_ADMIN() external view returns (bytes32);
function ROLE_GLOBAL_WALLETCHECK_ADMIN() external view returns (bytes32);
function ROLE_GLOBAL_VALIDATION_ADMIN() external view returns (bytes32);
function ROLE_GLOBAL_BACKDOOR_ADMIN() external view returns (bytes32);
function ruleRegistry() external view returns (address);
function init() external;
function createPolicy(
PolicyStorage.PolicyScalar calldata policyScalar,
address[] calldata attestors,
address[] calldata walletChecks
) external returns (uint32 policyId, bytes32 policyOwnerRoleId, bytes32 policyUserAdminRoleId);
function disablePolicy(uint32 policyId) external;
function updatePolicyScalar(
uint32 policyId,
PolicyStorage.PolicyScalar calldata policyScalar,
uint256 deadline
) external;
function updatePolicyDescription(uint32 policyId, string memory descriptionUtf8, uint256 deadline) external;
function updatePolicyRuleId(uint32 policyId, bytes32 ruleId, uint256 deadline) external;
function updatePolicyTtl(uint32 policyId, uint32 ttl, uint256 deadline) external;
function updatePolicyGracePeriod(uint32 policyId, uint32 gracePeriod, uint256 deadline) external;
function updatePolicyAllowApprovedCounterparties(
uint32 policyId,
bool allowApprovedCounterparties,uint256 deadline
) external;
function updatePolicyLock(uint32 policyId, bool locked, uint256 deadline) external;
function updatePolicyDisablementPeriod(uint32 policyId, uint256 disablementPeriod, uint256 deadline) external;
function setDeadline(uint32 policyId, uint256 deadline) external;
function addPolicyAttestors(uint32 policyId, address[] calldata attestors, uint256 deadline) external;
function removePolicyAttestors(uint32 policyId, address[] calldata attestors, uint256 deadline) external;
function addPolicyWalletChecks(uint32 policyId, address[] calldata walletChecks, uint256 deadline) external;
function removePolicyWalletChecks(uint32 policyId, address[] calldata walletChecks, uint256 deadline) external;
function addPolicyBackdoor(uint32 policyId, bytes32 backdoorId, uint256 deadline) external;
function removePolicyBackdoor(uint32 policyId, bytes32 backdoorId, uint256 deadline) external;
function admitAttestor(address attestor, string calldata uri) external;
function updateAttestorUri(address attestor, string calldata uri) external;
function removeAttestor(address attestor) external;
function admitWalletCheck(address walletCheck) external;
function removeWalletCheck(address walletCheck) external;
function admitBackdoor(uint256[2] memory pubKey) external;
function updateMinimumPolicyDisablementPeriod(uint256 minimumDisablementPeriod) external;
function policyOwnerRole(uint32 policyId) external pure returns (bytes32 ownerRole);
function policy(uint32 policyId)
external
returns (
PolicyStorage.PolicyScalar memory scalar,
address[] memory attestors,
address[] memory walletChecks,
bytes32[] memory backdoorRegimes,
uint256 deadline
);
function policyRawData(uint32 policyId)
external
view
returns(
uint256 deadline,
PolicyStorage.PolicyScalar memory scalarActive,
PolicyStorage.PolicyScalar memory scalarPending,
address[] memory attestorsActive,
address[] memory attestorsPendingAdditions,
address[] memory attestorsPendingRemovals,
address[] memory walletChecksActive,
address[] memory walletChecksPendingAdditions,
address[] memory walletChecksPendingRemovals,
bytes32[] memory backdoorsActive,
bytes32[] memory backdoorsPendingAdditions,
bytes32[] memory backdoorsPendingRemovals);
function policyScalarActive(uint32 policyId)
external
returns (PolicyStorage.PolicyScalar memory scalarActive);
function policyRuleId(uint32 policyId)
external
returns (bytes32 ruleId);
function policyTtl(uint32 policyId)
external
returns (uint32 ttl);
function policyAllowApprovedCounterparties(uint32 policyId)
external
returns (bool isAllowed);
function policyDisabled(uint32 policyId) external view returns (bool isDisabled);
function policyCanBeDisabled(uint32 policyId)
external
returns (bool canIndeed);
function policyAttestorCount(uint32 policyId) external returns (uint256 count);
function policyAttestorAtIndex(uint32 policyId, uint256 index)
external
returns (address attestor);
function policyAttestors(uint32 policyId) external returns (address[] memory attestors);
function isPolicyAttestor(uint32 policyId, address attestor)
external
returns (bool isIndeed);
function policyWalletCheckCount(uint32 policyId) external returns (uint256 count);
function policyWalletCheckAtIndex(uint32 policyId, uint256 index)
external
returns (address walletCheck);
function policyWalletChecks(uint32 policyId) external returns (address[] memory walletChecks);
function isPolicyWalletCheck(uint32 policyId, address walletCheck)
external
returns (bool isIndeed);
function policyBackdoorCount(uint32 policyId) external returns (uint256 count);
function policyBackdoorAtIndex(uint32 policyId, uint256 index) external returns (bytes32 backdoorId);
function policyBackdoors(uint32 policyId) external returns (bytes32[] memory backdoors);
function isPolicyBackdoor(uint32 policyId, bytes32 backdoorId) external returns (bool isIndeed);
function policyCount() external view returns (uint256 count);
function isPolicy(uint32 policyId) external view returns (bool isIndeed);
function globalAttestorCount() external view returns (uint256 count);
function globalAttestorAtIndex(uint256 index) external view returns (address attestor);
function isGlobalAttestor(address attestor) external view returns (bool isIndeed);
function globalWalletCheckCount() external view returns (uint256 count);
function globalWalletCheckAtIndex(uint256 index) external view returns(address walletCheck);
function isGlobalWalletCheck(address walletCheck) external view returns (bool isIndeed);
function globalBackdoorCount() external view returns (uint256 count);
function globalBackdoorAtIndex(uint256 index) external view returns (bytes32 backdoorId);
function isGlobalBackdoor(bytes32 backdoorId) external view returns (bool isIndeed);
function backdoorPubKey(bytes32 backdoorId) external view returns (uint256[2] memory pubKey);
function attestorUri(address attestor) external view returns (string memory);
function hasRole(bytes32 role, address user) external view returns (bool);
function minimumPolicyDisablementPeriod() external view returns (uint256 period);
}
文件 15 的 23:IRuleRegistry.sol
pragma solidity 0.8.14;
import "../lib/Bytes32Set.sol";
interface IRuleRegistry {
enum Operator {
Base,
Union,
Intersection,
Complement
}
struct Rule {
string description;
string uri;
Bytes32Set.Set operandSet;
Operator operator;
bool toxic;
}
event RuleRegistryDeployed(address deployer, address trustedForwarder);
event RuleRegistryInitialized(
address admin,
string universeDescription,
string universeUri,
string emptyDescription,
string emptyUri,
bytes32 universeRule,
bytes32 emptyRule
);
event CreateRule(
address indexed user,
bytes32 indexed ruleId,
string description,
string uri,
bool toxic,
Operator operator,
bytes32[] operands
);
event SetToxic(address admin, bytes32 ruleId, bool isToxic);
function ROLE_RULE_ADMIN() external view returns (bytes32);
function init(
string calldata universeDescription,
string calldata universeUri,
string calldata emptyDescription,
string calldata emptyUri
) external;
function createRule(
string calldata description,
string calldata uri,
Operator operator,
bytes32[] calldata operands
) external returns (bytes32 ruleId);
function setToxic(bytes32 ruleId, bool toxic) external;
function genesis() external view returns (bytes32 universeRule, bytes32 emptyRule);
function ruleCount() external view returns (uint256 count);
function ruleAtIndex(uint256 index) external view returns (bytes32 ruleId);
function isRule(bytes32 ruleId) external view returns (bool isIndeed);
function rule(bytes32 ruleId)
external
view
returns (
string memory description,
string memory uri,
Operator operator,
uint256 operandCount
);
function ruleDescription(bytes32 ruleId) external view returns (string memory description);
function ruleUri(bytes32 ruleId) external view returns (string memory uri);
function ruleIsToxic(bytes32 ruleId) external view returns (bool isIndeed);
function ruleOperator(bytes32 ruleId) external view returns (Operator operator);
function ruleOperandCount(bytes32 ruleId) external view returns (uint256 count);
function ruleOperandAtIndex(bytes32 ruleId, uint256 index)
external
view
returns (bytes32 operandId);
function generateRuleId(
string calldata description,
Operator operator,
bytes32[] calldata operands
) external pure returns (bytes32 ruleId);
}
文件 16 的 23:IWalletCheck.sol
pragma solidity 0.8.14;
interface IWalletCheck {
event Deployed(
address indexed admin,
address trustedForwarder,
address policyManager,
uint256 maximumConsentPeriod,
string uri);
event UpdateUri(address indexed admin, string uri);
event SetWalletCheck(address indexed admin, address indexed wallet, bool isWhitelisted);
function ROLE_WALLETCHECK_LIST_ADMIN() external view returns (bytes32);
function ROLE_WALLETCHECK_META_ADMIN() external view returns (bytes32);
function updateUri(string calldata uri_) external;
function setWalletCheck(address wallet, bool whitelisted, uint256 timestamp) external;
function checkWallet(
address observer,
address wallet,
uint32 admissionPolicyId
) external returns (bool passed);
}
文件 17 的 23:KeyringAccessControl.sol
pragma solidity 0.8.14;
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/metatx/ERC2771Context.sol";
abstract contract KeyringAccessControl is ERC2771Context, AccessControl {
address private constant NULL_ADDRESS = address(0);
bytes32[50] private _reservedSlots;
error Unacceptable(string reason);
error Unauthorized(
address sender,
string module,
string method,
bytes32 role,
string reason,
string context
);
constructor(address trustedForwarder) ERC2771Context(trustedForwarder) {
if (trustedForwarder == NULL_ADDRESS)
revert Unacceptable({
reason: "trustedForwarder cannot be empty"
});
}
function supportsInterface(bytes4 ) public view virtual override returns (bool) {
revert Unacceptable ({ reason: "ERC2165 is unsupported" });
}
function _checkRole(
bytes32 role,
address account,
string memory context
) internal view {
if (!hasRole(role, account))
revert Unauthorized({
sender: account,
module: "KeyringAccessControl",
method: "_checkRole",
role: role,
reason: "sender does not have the required role",
context: context
});
}
function _msgSender()
internal
view
virtual
override(Context, ERC2771Context)
returns (address sender)
{
return ERC2771Context._msgSender();
}
function _msgData()
internal
view
virtual
override(Context, ERC2771Context)
returns (bytes calldata)
{
return ERC2771Context._msgData();
}
}
文件 18 的 23:KeyringZkCredentialUpdater.sol
pragma solidity 0.8.14;
import "../interfaces/IKeyringZkCredentialUpdater.sol";
import "../interfaces/IPolicyManager.sol";
import "../interfaces/IKeyringCredentials.sol";
import "../interfaces/IRuleRegistry.sol";
import "../interfaces/IWalletCheck.sol";
import "../interfaces/IKeyringZkVerifier.sol";
import "../lib/Pack12x20.sol";
import "../access/KeyringAccessControl.sol";
contract KeyringZkCredentialUpdater is
IKeyringZkCredentialUpdater,
KeyringAccessControl
{
using Pack12x20 for uint32[12];
using Pack12x20 for uint256;
address private constant NULL_ADDRESS = address(0);
bytes32 private constant NULL_BYTES32 = bytes32(0);
IRuleRegistry private immutable RULE_REGISTRY;
address public immutable override POLICY_MANAGER;
address public immutable override KEYRING_CREDENTIALS;
address public immutable override KEYRING_ZK_VERIFIER;
constructor(
address trustedForwarder,
address keyringCredentials,
address policyManager,
address keyringZkVerifier
) KeyringAccessControl(trustedForwarder) {
if (keyringCredentials == NULL_ADDRESS)
revert Unacceptable({
reason: "keyringCredentials cannot be empty"
});
if (policyManager == NULL_ADDRESS)
revert Unacceptable({
reason: "policyManager cannot be empty"
});
if (keyringZkVerifier == NULL_ADDRESS)
revert Unacceptable({
reason: "keyringZkVerifier cannot be empty"
});
RULE_REGISTRY = IRuleRegistry(IPolicyManager(policyManager).ruleRegistry());
_grantRole(DEFAULT_ADMIN_ROLE, _msgSender());
POLICY_MANAGER = policyManager;
KEYRING_CREDENTIALS = keyringCredentials;
KEYRING_ZK_VERIFIER = keyringZkVerifier;
emit CredentialUpdaterDeployed(
_msgSender(),
trustedForwarder,
keyringCredentials,
policyManager,
keyringZkVerifier
);
}
function updateCredentials(
address attestor,
IKeyringZkVerifier.IdentityMembershipProof calldata membershipProof,
IKeyringZkVerifier.IdentityAuthorisationProof calldata authorizationProof
) external override {
bytes32 requireBackdoor;
if (!IPolicyManager(POLICY_MANAGER).isGlobalAttestor(attestor))
revert Unacceptable({ reason: "attestor unacceptable" });
uint32 policyId;
address sender = _msgSender();
address trader = address(uint160(authorizationProof.tradingAddress));
if (sender != trader)
revert Unacceptable ({ reason: "only trader can update trader credentials" });
bytes32 root = bytes32(membershipProof.root);
uint32[12] memory policyList0 = unpack12x20(authorizationProof.policyDisclosures[0]);
uint32[12] memory policyList1 = unpack12x20(authorizationProof.policyDisclosures[1]);
if(!IKeyringZkVerifier(KEYRING_ZK_VERIFIER).checkClaim(
membershipProof,
authorizationProof
)) revert Unacceptable({
reason: "Proof unacceptable"});
uint256 rootTime = IDegradable(attestor).subjectUpdates(root);
for(uint256 i = 0; i < 24; i++) {
policyId = (i / 12 == 0) ? policyList0[i % 12] : policyList1[i % 12];
if(policyId == 0) break;
if(!checkPolicy(policyId, attestor))
revert Unacceptable({
reason: "policy or attestor unacceptable"
});
IKeyringCredentials(KEYRING_CREDENTIALS).setCredential(
trader,
policyId,
rootTime);
uint256 policyBackdoorCount = IPolicyManager(POLICY_MANAGER).policyBackdoorCount(policyId);
if (policyBackdoorCount > 1) revert Unacceptable({ reason: "multiple policy backdoors are not supported" });
if (policyBackdoorCount == 1) {
if (requireBackdoor == NULL_BYTES32) {
requireBackdoor = IPolicyManager(POLICY_MANAGER).policyBackdoorAtIndex(policyId, 0);
} else {
if(requireBackdoor != IPolicyManager(POLICY_MANAGER).policyBackdoorAtIndex(policyId,0))
revert Unacceptable({
reason: "all policies in the proof must rely on the same backdoor or no backdoor"
});
}
}
}
if (requireBackdoor != NULL_BYTES32) {
uint256[2] memory requirePubKey = IPolicyManager(POLICY_MANAGER).backdoorPubKey(requireBackdoor);
if (requirePubKey[0] != authorizationProof.regimeKey[0] ||
requirePubKey[1] != authorizationProof.regimeKey[1])
{
revert Unacceptable ({
reason: "Proof does not contain required backdoor regimeKey"
});
}
}
emit AcceptCredentialUpdate(
sender,
trader,
membershipProof,
authorizationProof,
rootTime);
}
function checkPolicy(
uint32 policyId,
address attestor
) public override returns (bool acceptable)
{
IPolicyManager p = IPolicyManager(POLICY_MANAGER);
if(!p.isPolicy(policyId)) return false;
PolicyStorage.PolicyScalar memory policyScalar =
IPolicyManager(POLICY_MANAGER).policyScalarActive(policyId);
acceptable = !(RULE_REGISTRY.ruleIsToxic(policyScalar.ruleId)) &&
p.isPolicyAttestor(policyId, attestor);
}
function pack12x20(uint32[12] calldata input) public pure override returns (uint256 packed) {
packed = input.pack();
}
function unpack12x20(uint256 packed) public pure override returns (uint32[12] memory unpacked) {
unpacked = packed.unpack();
}
}
文件 19 的 23:Math.sol
pragma solidity ^0.8.0;
library Math {
enum Rounding {
Down,
Up,
Zero
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
return a == 0 ? 0 : (a - 1) / b + 1;
}
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
uint256 prod0;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
return prod0 / denominator;
}
require(denominator > prod1, "Math: mulDiv overflow");
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (~denominator + 1);
assembly {
denominator := div(denominator, twos)
prod0 := div(prod0, twos)
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
return result;
}
}
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 result = 1 << (log2(a) >> 1);
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}
文件 20 的 23:Pack12x20.sol
pragma solidity 0.8.14;
library Pack12x20 {
error OutOfRange(uint32 input);
uint8 constant FIELD_SIZE = 20;
uint256 constant MASK = 2 ** FIELD_SIZE - 1;
function pack(uint32[12] calldata input)
internal pure returns(uint256 packed)
{
if (input[0] > MASK) revert OutOfRange(input[0]);
packed = uint256(input[0]);
packed = packed << FIELD_SIZE;
if (input[1] > MASK) revert OutOfRange(input[1]);
packed = packed + input[1];
packed = packed << FIELD_SIZE;
if (input[2] > MASK) revert OutOfRange(input[2]);
packed = packed + input[2];
packed = packed << FIELD_SIZE;
if (input[3] > MASK) revert OutOfRange(input[3]);
packed = packed + input[3];
packed = packed << FIELD_SIZE;
if (input[4] > MASK) revert OutOfRange(input[4]);
packed = packed + input[4];
packed = packed << FIELD_SIZE;
if (input[5] > MASK) revert OutOfRange(input[5]);
packed = packed + input[5];
packed = packed << FIELD_SIZE;
if (input[6] > MASK) revert OutOfRange(input[6]);
packed = packed + input[6];
packed = packed << FIELD_SIZE;
if (input[7] > MASK) revert OutOfRange(input[7]);
packed = packed + input[7];
packed = packed << FIELD_SIZE;
if (input[8] > MASK) revert OutOfRange(input[8]);
packed = packed + input[8];
packed = packed << FIELD_SIZE;
if (input[9] > MASK) revert OutOfRange(input[9]);
packed = packed + input[9];
packed = packed << FIELD_SIZE;
if (input[10] > MASK) revert OutOfRange(input[10]);
packed = packed + input[10];
packed = packed << FIELD_SIZE;
if (input[11] > MASK) revert OutOfRange(input[11]);
packed = packed + input[11];
}
function unpack(uint256 packed)
internal pure returns(uint32[12] memory output)
{
require(
packed == uint256(uint240(packed)),
"input out of range"
);
output[11] = uint32(packed & MASK);
packed = packed >> FIELD_SIZE;
output[10] = uint32(packed & MASK);
packed = packed >> FIELD_SIZE;
output[9] = uint32(packed & MASK);
packed = packed >> FIELD_SIZE;
output[8]= uint32(packed & MASK);
packed = packed >> FIELD_SIZE;
output[7] = uint32(packed & MASK);
packed = packed >> FIELD_SIZE;
output[6] = uint32(packed & MASK);
packed = packed >> FIELD_SIZE;
output[5] = uint32(packed & MASK);
packed = packed >> FIELD_SIZE;
output[4] = uint32(packed & MASK);
packed = packed >> FIELD_SIZE;
output[3] = uint32(packed & MASK);
packed = packed >> FIELD_SIZE;
output[2] = uint32(packed & MASK);
packed = packed >> FIELD_SIZE;
output[1] = uint32(packed & MASK);
packed = packed >> FIELD_SIZE;
output[0] = uint32(packed);
}
}
文件 21 的 23:PolicyStorage.sol
pragma solidity 0.8.14;
import "./AddressSet.sol";
import "../interfaces/IRuleRegistry.sol";
import "../interfaces/IIdentityTree.sol";
import "../interfaces/IDegradable.sol";
import "../interfaces/IKeyringCredentials.sol";
library PolicyStorage {
using AddressSet for AddressSet.Set;
using Bytes32Set for Bytes32Set.Set;
uint32 private constant MAX_POLICIES = 2 ** 20;
uint32 private constant MAX_TTL = 2 * 365 days;
uint256 public constant MAX_DISABLEMENT_PERIOD = 120 days;
uint256 private constant MAX_BACKDOORS = 1;
uint256 private constant UNIVERSAL_RULE = 0;
address private constant NULL_ADDRESS = address(0);
error Unacceptable(string reason);
struct App {
uint256 minimumPolicyDisablementPeriod;
Policy[] policies;
AddressSet.Set globalWalletCheckSet;
AddressSet.Set globalAttestorSet;
mapping(address => string) attestorUris;
Bytes32Set.Set backdoorSet;
mapping(bytes32 => uint256[2]) backdoorPubKey;
}
struct PolicyScalar {
bytes32 ruleId;
string descriptionUtf8;
uint32 ttl;
uint32 gracePeriod;
bool allowApprovedCounterparties;
uint256 disablementPeriod;
bool locked;
}
struct PolicyAttestors {
AddressSet.Set activeSet;
AddressSet.Set pendingAdditionSet;
AddressSet.Set pendingRemovalSet;
}
struct PolicyWalletChecks {
AddressSet.Set activeSet;
AddressSet.Set pendingAdditionSet;
AddressSet.Set pendingRemovalSet;
}
struct PolicyBackdoors {
Bytes32Set.Set activeSet;
Bytes32Set.Set pendingAdditionSet;
Bytes32Set.Set pendingRemovalSet;
}
struct Policy {
bool disabled;
uint256 deadline;
PolicyScalar scalarActive;
PolicyScalar scalarPending;
PolicyAttestors attestors;
PolicyWalletChecks walletChecks;
PolicyBackdoors backdoors;
}
function disablePolicy(
Policy storage policyObj
) public
{
if (!policyHasFailed(policyObj))
revert Unacceptable({
reason: "only failed policies can be disabled"
});
policyObj.disabled = true;
policyObj.deadline = ~uint(0);
}
function policyHasFailed(
Policy storage policyObj
) public view returns (bool hasIndeed)
{
if (policyObj.disabled == true)
revert Unacceptable({
reason: "policy is already disabled"
});
uint256 i;
uint256 disablementPeriod = policyObj.scalarActive.disablementPeriod;
bool allAttestorsHaveFailed = true;
uint256 policyAttestorsCount = policyObj.attestors.activeSet.count();
for (i=0; i<policyAttestorsCount; i++) {
uint256 lastUpdate = IDegradable(policyObj.attestors.activeSet.keyAtIndex(i)).lastUpdate();
if (lastUpdate > 0) {
if(block.timestamp < lastUpdate + disablementPeriod) {
allAttestorsHaveFailed = false;
}
} else {
allAttestorsHaveFailed = false;
}
}
if(!allAttestorsHaveFailed) {
uint256 policyWalletChecksCount = policyObj.walletChecks.activeSet.count();
for (i=0; i<policyWalletChecksCount; i++) {
uint256 lastUpdate = IDegradable(policyObj.walletChecks.activeSet.keyAtIndex(i)).lastUpdate();
if (lastUpdate > 0) {
if(block.timestamp > lastUpdate + disablementPeriod) return true;
}
}
}
hasIndeed = allAttestorsHaveFailed;
}
function updateMinimumPolicyDisablementPeriod(
App storage self,
uint256 minimumDisablementPeriod
) public
{
if (minimumDisablementPeriod >= MAX_DISABLEMENT_PERIOD)
revert Unacceptable({
reason: "minimum disablement period is too long"
});
self.minimumPolicyDisablementPeriod = minimumDisablementPeriod;
}
function insertGlobalAttestor(
App storage self,
address attestor,
string memory uri
) public
{
if (attestor == NULL_ADDRESS)
revert Unacceptable({
reason: "attestor cannot be empty"
});
if (bytes(uri).length == 0)
revert Unacceptable({
reason: "uri cannot be empty"
});
self.globalAttestorSet.insert(attestor, "PolicyStorage:insertGlobalAttestor");
self.attestorUris[attestor] = uri;
}
function updateGlobalAttestorUri(
App storage self,
address attestor,
string memory uri
) public
{
if (!self.globalAttestorSet.exists(attestor))
revert Unacceptable({
reason: "attestor not found"
});
if (bytes(uri).length == 0)
revert Unacceptable({
reason: "uri cannot be empty"
});
self.attestorUris[attestor] = uri;
}
function removeGlobalAttestor(
App storage self,
address attestor
) public
{
self.globalAttestorSet.remove(attestor, "PolicyStorage:removeGlobalAttestor");
}
function insertGlobalWalletCheck(
App storage self,
address walletCheck
) public
{
if (walletCheck == NULL_ADDRESS)
revert Unacceptable({
reason: "walletCheck cannot be empty"
});
self.globalWalletCheckSet.insert(walletCheck, "PolicyStorage:insertGlobalWalletCheck");
}
function removeGlobalWalletCheck(
App storage self,
address walletCheck
) public
{
self.globalWalletCheckSet.remove(walletCheck, "PolicyStorage:removeGlobalWalletCheck");
}
function insertGlobalBackdoor(
App storage self,
uint256[2] calldata pubKey
) public returns (bytes32 id)
{
id = keccak256(abi.encodePacked(pubKey));
self.backdoorPubKey[id] = pubKey;
self.backdoorSet.insert(
id,
"PolicyStorage:insertGlobalBackdoor"
);
}
function newPolicy(
App storage self,
PolicyScalar calldata policyScalar,
address[] memory attestors,
address[] memory walletChecks,
address ruleRegistry
) public returns (uint32 policyId)
{
(bytes32 universeRule, bytes32 emptyRule) = IRuleRegistry(ruleRegistry).genesis();
if (
attestors.length < 1 &&
policyScalar.ruleId != universeRule &&
policyScalar.ruleId != emptyRule)
{
revert Unacceptable({
reason: "every policy needs at least one attestor"
});
}
uint256 i;
self.policies.push();
policyId = uint32(self.policies.length - 1);
if (policyId >= MAX_POLICIES)
revert Unacceptable({
reason: "max policies exceeded"
});
Policy storage policyObj = policyRawData(self, policyId);
uint256 deadline = block.timestamp;
writePolicyScalar(
self,
policyId,
policyScalar,
ruleRegistry,
deadline
);
processStaged(policyObj);
for (i=0; i<attestors.length; i++) {
address attestor = attestors[i];
if (!self.globalAttestorSet.exists(attestor))
revert Unacceptable({
reason: "attestor not found"
});
policyObj.attestors.activeSet.insert(attestor, "PolicyStorage:newPolicy");
}
for (i=0; i<walletChecks.length; i++) {
address walletCheck = walletChecks[i];
if (!self.globalWalletCheckSet.exists(walletCheck))
revert Unacceptable({
reason: "walletCheck not found"
});
policyObj.walletChecks.activeSet.insert(walletCheck, "PolicyStorage:newPolicy");
}
}
function policyRawData(
App storage self,
uint32 policyId
) public view returns (Policy storage policyInfo)
{
policyInfo = self.policies[policyId];
}
function _processAdditions(
AddressSet.Set storage activeSet,
AddressSet.Set storage additionSet
) private {
uint256 count = additionSet.count();
while (count > 0) {
address entity = additionSet.keyAtIndex(additionSet.count() - 1);
activeSet.insert(entity, "policyStorage:_processAdditions");
additionSet.remove(entity, "policyStorage:_processAdditions");
count--;
}
}
function _processAdditions(
Bytes32Set.Set storage activeSet,
Bytes32Set.Set storage additionSet
) private {
uint256 count = additionSet.count();
while (count > 0) {
bytes32 entity = additionSet.keyAtIndex(additionSet.count() - 1);
activeSet.insert(entity, "policyStorage:_processAdditions");
additionSet.remove(entity, "policyStorage:_processAdditions");
count--;
}
}
function _processRemovals(
AddressSet.Set storage activeSet,
AddressSet.Set storage removalSet
) private {
uint256 count = removalSet.count();
while (count > 0) {
address entity = removalSet.keyAtIndex(removalSet.count() - 1);
activeSet.remove(entity, "policyStorage:_processRemovals");
removalSet.remove(entity, "policyStorage:_processRemovals");
count--;
}
}
function _processRemovals(
Bytes32Set.Set storage activeSet,
Bytes32Set.Set storage removalSet
) private {
uint256 count = removalSet.count();
while (count > 0) {
bytes32 entity = removalSet.keyAtIndex(removalSet.count() - 1);
activeSet.remove(entity, "policyStorage:_processRemovals");
removalSet.remove(entity, "policyStorage:_processRemovals");
count--;
}
}
function processStaged(Policy storage policyObj) public {
uint256 deadline = policyObj.deadline;
if (deadline > 0 && deadline <= block.timestamp) {
policyObj.scalarActive = policyObj.scalarPending;
_processAdditions(policyObj.attestors.activeSet, policyObj.attestors.pendingAdditionSet);
_processRemovals(policyObj.attestors.activeSet, policyObj.attestors.pendingRemovalSet);
_processAdditions(policyObj.walletChecks.activeSet, policyObj.walletChecks.pendingAdditionSet);
_processRemovals(policyObj.walletChecks.activeSet, policyObj.walletChecks.pendingRemovalSet);
_processAdditions(policyObj.backdoors.activeSet, policyObj.backdoors.pendingAdditionSet);
_processRemovals(policyObj.backdoors.activeSet, policyObj.backdoors.pendingRemovalSet);
policyObj.deadline = 0;
}
}
function checkLock(
Policy storage policyObj
) public view
{
if (isLocked(policyObj) || policyObj.disabled)
revert Unacceptable({
reason: "policy is locked"
});
}
function isLocked(Policy storage policyObj) public view returns(bool isIndeed) {
isIndeed = policyObj.scalarActive.locked;
}
function setDeadline(
Policy storage policyObj,
uint256 deadline
) public
{
checkLock(policyObj);
if (deadline != 0 &&
(deadline < block.timestamp + policyObj.scalarActive.gracePeriod)
)
revert Unacceptable({
reason: "deadline in the past or too soon"
});
policyObj.deadline = deadline;
}
function writePolicyScalar(
App storage self,
uint32 policyId,
PolicyStorage.PolicyScalar calldata policyScalar,
address ruleRegistry,
uint256 deadline
) public {
PolicyStorage.Policy storage policyObj = policyRawData(self, policyId);
processStaged(policyObj);
writeRuleId(policyObj, policyScalar.ruleId, ruleRegistry);
writeDescription(policyObj, policyScalar.descriptionUtf8);
writeTtl(policyObj, policyScalar.ttl);
writeGracePeriod(policyObj, policyScalar.gracePeriod);
writeAllowApprovedCounterparties(policyObj, policyScalar.allowApprovedCounterparties);
writePolicyLock(policyObj, policyScalar.locked);
writeDisablementPeriod(self, policyId, policyScalar.disablementPeriod);
setDeadline(policyObj, deadline);
}
function writeRuleId(
Policy storage self,
bytes32 ruleId,
address ruleRegistry
) public
{
if (!IRuleRegistry(ruleRegistry).isRule(ruleId))
revert Unacceptable({
reason: "rule not found"
});
self.scalarPending.ruleId = ruleId;
}
function writeDescription(
Policy storage self,
string memory descriptionUtf8
) public
{
if (bytes(descriptionUtf8).length == 0)
revert Unacceptable({
reason: "descriptionUtf8 cannot be empty"
});
self.scalarPending.descriptionUtf8 = descriptionUtf8;
}
function writeTtl(
Policy storage self,
uint32 ttl
) public
{
if (ttl > MAX_TTL)
revert Unacceptable({ reason: "ttl exceeds maximum duration" });
self.scalarPending.ttl = ttl;
}
function writeGracePeriod(
Policy storage self,
uint32 gracePeriod
) public
{
self.scalarPending.gracePeriod = gracePeriod;
}
function writeAllowApprovedCounterparties(
Policy storage self,
bool allowApprovedCounterparties
) public
{
self.scalarPending.allowApprovedCounterparties = allowApprovedCounterparties;
}
function writePolicyLock(
Policy storage self,
bool setPolicyLocked
) public
{
self.scalarPending.locked = setPolicyLocked;
}
function writeDisablementPeriod(
App storage self,
uint32 policyId,
uint256 disablementPeriod
) public {
if (disablementPeriod < self.minimumPolicyDisablementPeriod) {
revert Unacceptable({
reason: "disablement period is too short"
});
}
if (disablementPeriod >= MAX_DISABLEMENT_PERIOD) {
revert Unacceptable({
reason: "disablement period is too long"
});
}
Policy storage policyObj = self.policies[policyId];
policyObj.scalarPending.disablementPeriod = disablementPeriod;
}
function writeAttestorAdditions(
App storage self,
Policy storage policyObj,
address[] calldata attestors
) public
{
for (uint i = 0; i < attestors.length; i++) {
_writeAttestorAddition(self, policyObj, attestors[i]);
}
}
function _writeAttestorAddition(
App storage self,
Policy storage policyObj,
address attestor
) private
{
if (!self.globalAttestorSet.exists(attestor))
revert Unacceptable({
reason: "attestor not found"
});
if (policyObj.attestors.pendingRemovalSet.exists(attestor)) {
policyObj.attestors.pendingRemovalSet.remove(attestor, "PolicyStorage:_writeAttestorAddition");
} else {
if (policyObj.attestors.activeSet.exists(attestor)) {
revert Unacceptable({
reason: "attestor already in policy"
});
}
policyObj.attestors.pendingAdditionSet.insert(attestor, "PolicyStorage:_writeAttestorAddition");
}
}
function writeAttestorRemovals(
Policy storage self,
address[] calldata attestors
) public
{
for (uint i = 0; i < attestors.length; i++) {
_writeAttestorRemoval(self, attestors[i]);
}
}
function _writeAttestorRemoval(
Policy storage self,
address attestor
) private
{
uint currentAttestorCount = self.attestors.activeSet.count();
uint pendingAdditionsCount = self.attestors.pendingAdditionSet.count();
uint pendingRemovalsCount = self.attestors.pendingRemovalSet.count();
if (currentAttestorCount + pendingAdditionsCount - pendingRemovalsCount < 2) {
revert Unacceptable({
reason: "Cannot remove the last attestor. Add a replacement first"
});
}
if (self.attestors.pendingAdditionSet.exists(attestor)) {
self.attestors.pendingAdditionSet.remove(attestor, "PolicyStorage:_writeAttestorRemoval");
} else {
if (!self.attestors.activeSet.exists(attestor)) {
revert Unacceptable({
reason: "attestor not found"
});
}
self.attestors.pendingRemovalSet.insert(attestor, "PolicyStorage:_writeAttestorRemoval");
}
}
function writeWalletCheckAdditions(
App storage self,
Policy storage policyObj,
address[] memory walletChecks
) public
{
for (uint i = 0; i < walletChecks.length; i++) {
_writeWalletCheckAddition(self, policyObj, walletChecks[i]);
}
}
function _writeWalletCheckAddition(
App storage self,
Policy storage policyObj,
address walletCheck
) private
{
if (!self.globalWalletCheckSet.exists(walletCheck))
revert Unacceptable({
reason: "walletCheck not found"
});
if (policyObj.walletChecks.pendingRemovalSet.exists(walletCheck)) {
policyObj.walletChecks.pendingRemovalSet.remove(walletCheck, "PolicyStorage:_writeWalletCheckAddition");
} else {
if (policyObj.walletChecks.activeSet.exists(walletCheck)) {
revert Unacceptable({
reason: "walletCheck already in policy"
});
}
if (policyObj.walletChecks.pendingAdditionSet.exists(walletCheck)) {
revert Unacceptable({
reason: "walletCheck addition already scheduled"
});
}
policyObj.walletChecks.pendingAdditionSet.insert(walletCheck, "PolicyStorage:_writeWalletCheckAddition");
}
}
function writeWalletCheckRemovals(
Policy storage self,
address[] memory walletChecks
) public
{
for (uint i = 0; i < walletChecks.length; i++) {
_writeWalletCheckRemoval(self, walletChecks[i]);
}
}
function _writeWalletCheckRemoval(
Policy storage self,
address walletCheck
) private
{
if (self.walletChecks.pendingAdditionSet.exists(walletCheck)) {
self.walletChecks.pendingAdditionSet.remove(walletCheck, "PolicyStorage:_writeWalletCheckRemoval");
} else {
if (!self.walletChecks.activeSet.exists(walletCheck)) {
revert Unacceptable({
reason: "walletCheck is not in policy"
});
}
if (self.walletChecks.pendingRemovalSet.exists(walletCheck)) {
revert Unacceptable({
reason: "walletCheck removal already scheduled"
});
}
self.walletChecks.pendingRemovalSet.insert(walletCheck, "PolicyStorage:_writeWalletCheckRemoval");
}
}
function writeBackdoorAddition(
App storage self,
Policy storage policyObj,
bytes32 backdoorId
) public {
if (!self.backdoorSet.exists(backdoorId)) {
revert Unacceptable({
reason: "unknown backdoor"
});
}
if (policyObj.backdoors.pendingRemovalSet.exists(backdoorId)) {
policyObj.backdoors.pendingRemovalSet.remove(backdoorId,
"PolicyStorage:writeBackdoorAddition");
} else {
if (policyObj.backdoors.activeSet.exists(backdoorId)) {
revert Unacceptable({
reason: "backdoor exists in policy"
});
}
if (policyObj.backdoors.pendingAdditionSet.exists(backdoorId)) {
revert Unacceptable({
reason: "backdoor addition already scheduled"
});
}
policyObj.backdoors.pendingAdditionSet.insert(backdoorId,
"PolicyStorage:_writeWalletCheckAddition");
_checkBackdoorConfiguration(policyObj);
}
}
function writeBackdoorRemoval(
Policy storage self,
bytes32 backdoorId
) public
{
if (self.backdoors.pendingAdditionSet.exists(backdoorId)) {
self.backdoors.pendingAdditionSet.remove(backdoorId,
"PolicyStorage:writeBackdoorRemoval");
} else {
if (!self.backdoors.activeSet.exists(backdoorId)) {
revert Unacceptable({
reason: "backdoor is not in policy"
});
}
if (self.backdoors.pendingRemovalSet.exists(backdoorId)) {
revert Unacceptable({
reason: "backdoor removal already scheduled"
});
}
self.backdoors.pendingRemovalSet.insert(backdoorId,
"PolicyStorage:writeBackdoorRemoval");
}
}
function _checkBackdoorConfiguration(
Policy storage self
) internal view {
uint256 activeCount = self.backdoors.activeSet.count();
uint256 pendingAdditionsCount = self.backdoors.pendingAdditionSet.count();
uint256 pendingRemovalsCount = self.backdoors.pendingRemovalSet.count();
if(activeCount + pendingAdditionsCount - pendingRemovalsCount > MAX_BACKDOORS) {
revert Unacceptable({ reason: "too many backdoors requested" });
}
}
function policy(App storage self, uint32 policyId)
public
returns (Policy storage policyObj)
{
policyObj = self.policies[policyId];
processStaged(policyObj);
}
}
文件 22 的 23:SignedMath.sol
pragma solidity ^0.8.0;
library SignedMath {
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
function average(int256 a, int256 b) internal pure returns (int256) {
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
function abs(int256 n) internal pure returns (uint256) {
unchecked {
return uint256(n >= 0 ? n : -n);
}
}
}
文件 23 的 23:Strings.sol
pragma solidity ^0.8.0;
import "./math/Math.sol";
import "./math/SignedMath.sol";
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
function toString(int256 value) internal pure returns (string memory) {
return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
}
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
function equal(string memory a, string memory b) internal pure returns (bool) {
return keccak256(bytes(a)) == keccak256(bytes(b));
}
}
{
"compilationTarget": {
"contracts/credentialUpdater/KeyringZkCredentialUpdater.sol": "KeyringZkCredentialUpdater"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "none",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"trustedForwarder","type":"address"},{"internalType":"address","name":"keyringCredentials","type":"address"},{"internalType":"address","name":"policyManager","type":"address"},{"internalType":"address","name":"keyringZkVerifier","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint32","name":"input","type":"uint32"}],"name":"OutOfRange","type":"error"},{"inputs":[{"internalType":"string","name":"reason","type":"string"}],"name":"Unacceptable","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string","name":"module","type":"string"},{"internalType":"string","name":"method","type":"string"},{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"string","name":"reason","type":"string"},{"internalType":"string","name":"context","type":"string"}],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"trader","type":"address"},{"components":[{"components":[{"internalType":"uint256[2]","name":"a","type":"uint256[2]"},{"internalType":"uint256[2][2]","name":"b","type":"uint256[2][2]"},{"internalType":"uint256[2]","name":"c","type":"uint256[2]"}],"internalType":"struct IKeyringZkVerifier.Groth16Proof","name":"proof","type":"tuple"},{"internalType":"uint256","name":"root","type":"uint256"},{"internalType":"uint256","name":"nullifierHash","type":"uint256"},{"internalType":"uint256","name":"signalHash","type":"uint256"},{"internalType":"uint256","name":"externalNullifier","type":"uint256"}],"indexed":false,"internalType":"struct IKeyringZkVerifier.IdentityMembershipProof","name":"membershipProof","type":"tuple"},{"components":[{"components":[{"internalType":"uint256[2]","name":"a","type":"uint256[2]"},{"internalType":"uint256[2][2]","name":"b","type":"uint256[2][2]"},{"internalType":"uint256[2]","name":"c","type":"uint256[2]"}],"internalType":"struct IKeyringZkVerifier.Groth16Proof","name":"proof","type":"tuple"},{"components":[{"internalType":"uint256[2]","name":"c1","type":"uint256[2]"},{"internalType":"uint256[2]","name":"c2","type":"uint256[2]"}],"internalType":"struct IKeyringZkVerifier.Backdoor","name":"backdoor","type":"tuple"},{"internalType":"uint256","name":"externalNullifier","type":"uint256"},{"internalType":"uint256","name":"nullifierHash","type":"uint256"},{"internalType":"uint256[2]","name":"policyDisclosures","type":"uint256[2]"},{"internalType":"uint256","name":"tradingAddress","type":"uint256"},{"internalType":"uint256[2]","name":"regimeKey","type":"uint256[2]"}],"indexed":false,"internalType":"struct IKeyringZkVerifier.IdentityAuthorisationProof","name":"authorizationProof","type":"tuple"},{"indexed":false,"internalType":"uint256","name":"rootTime","type":"uint256"}],"name":"AcceptCredentialUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"address","name":"identityTree","type":"address"}],"name":"AdmitIdentityTree","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"deployer","type":"address"},{"indexed":false,"internalType":"address","name":"trustedForwarder","type":"address"},{"indexed":false,"internalType":"address","name":"keyringCache","type":"address"},{"indexed":false,"internalType":"address","name":"admissionPolicyManager","type":"address"},{"indexed":false,"internalType":"address","name":"keyringZkVerifier","type":"address"}],"name":"CredentialUpdaterDeployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"address","name":"identityTree","type":"address"}],"name":"RemoveIdentityTree","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"KEYRING_CREDENTIALS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"KEYRING_ZK_VERIFIER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POLICY_MANAGER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"policyId","type":"uint32"},{"internalType":"address","name":"attestor","type":"address"}],"name":"checkPolicy","outputs":[{"internalType":"bool","name":"acceptable","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"isTrustedForwarder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32[12]","name":"input","type":"uint32[12]"}],"name":"pack12x20","outputs":[{"internalType":"uint256","name":"packed","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"packed","type":"uint256"}],"name":"unpack12x20","outputs":[{"internalType":"uint32[12]","name":"unpacked","type":"uint32[12]"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"attestor","type":"address"},{"components":[{"components":[{"internalType":"uint256[2]","name":"a","type":"uint256[2]"},{"internalType":"uint256[2][2]","name":"b","type":"uint256[2][2]"},{"internalType":"uint256[2]","name":"c","type":"uint256[2]"}],"internalType":"struct IKeyringZkVerifier.Groth16Proof","name":"proof","type":"tuple"},{"internalType":"uint256","name":"root","type":"uint256"},{"internalType":"uint256","name":"nullifierHash","type":"uint256"},{"internalType":"uint256","name":"signalHash","type":"uint256"},{"internalType":"uint256","name":"externalNullifier","type":"uint256"}],"internalType":"struct IKeyringZkVerifier.IdentityMembershipProof","name":"membershipProof","type":"tuple"},{"components":[{"components":[{"internalType":"uint256[2]","name":"a","type":"uint256[2]"},{"internalType":"uint256[2][2]","name":"b","type":"uint256[2][2]"},{"internalType":"uint256[2]","name":"c","type":"uint256[2]"}],"internalType":"struct IKeyringZkVerifier.Groth16Proof","name":"proof","type":"tuple"},{"components":[{"internalType":"uint256[2]","name":"c1","type":"uint256[2]"},{"internalType":"uint256[2]","name":"c2","type":"uint256[2]"}],"internalType":"struct IKeyringZkVerifier.Backdoor","name":"backdoor","type":"tuple"},{"internalType":"uint256","name":"externalNullifier","type":"uint256"},{"internalType":"uint256","name":"nullifierHash","type":"uint256"},{"internalType":"uint256[2]","name":"policyDisclosures","type":"uint256[2]"},{"internalType":"uint256","name":"tradingAddress","type":"uint256"},{"internalType":"uint256[2]","name":"regimeKey","type":"uint256[2]"}],"internalType":"struct IKeyringZkVerifier.IdentityAuthorisationProof","name":"authorizationProof","type":"tuple"}],"name":"updateCredentials","outputs":[],"stateMutability":"nonpayable","type":"function"}]