编译器
0.6.12+commit.27d51765
文件 1 的 11:EnumerableSet.sol
pragma solidity ^0.6.0;
library EnumerableSet {
struct Set {
bytes32[] _values;
mapping (bytes32 => uint256) _indexes;
}
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
function _remove(Set storage set, bytes32 value) private returns (bool) {
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
bytes32 lastvalue = set._values[lastIndex];
set._values[toDeleteIndex] = lastvalue;
set._indexes[lastvalue] = toDeleteIndex + 1;
set._values.pop();
delete set._indexes[value];
return true;
} else {
return false;
}
}
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
function _at(Set storage set, uint256 index) private view returns (bytes32) {
require(set._values.length > index, "EnumerableSet: index out of bounds");
return set._values[index];
}
struct AddressSet {
Set _inner;
}
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(value)));
}
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(value)));
}
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(value)));
}
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint256(_at(set._inner, index)));
}
struct UintSet {
Set _inner;
}
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
}
文件 2 的 11:ExtensionBase.sol
pragma solidity 0.6.12;
import "../../core/fund/comptroller/IComptroller.sol";
import "../../core/fund/vault/IVault.sol";
import "../IExtension.sol";
abstract contract ExtensionBase is IExtension {
mapping(address => address) internal comptrollerProxyToVaultProxy;
function activateForFund(bool) external virtual override {
return;
}
function deactivateForFund() external virtual override {
return;
}
function receiveCallFromComptroller(
address,
uint256,
bytes calldata
) external virtual override {
revert("receiveCallFromComptroller: Unimplemented for Extension");
}
function setConfigForFund(bytes calldata) external virtual override {
return;
}
function __setValidatedVaultProxy(address _comptrollerProxy)
internal
returns (address vaultProxy_)
{
require(
comptrollerProxyToVaultProxy[_comptrollerProxy] == address(0),
"__setValidatedVaultProxy: Already set"
);
vaultProxy_ = IComptroller(_comptrollerProxy).getVaultProxy();
require(vaultProxy_ != address(0), "__setValidatedVaultProxy: Missing vaultProxy");
require(
_comptrollerProxy == IVault(vaultProxy_).getAccessor(),
"__setValidatedVaultProxy: Not the VaultProxy accessor"
);
comptrollerProxyToVaultProxy[_comptrollerProxy] = vaultProxy_;
return vaultProxy_;
}
function getVaultProxyForFund(address _comptrollerProxy)
public
view
returns (address vaultProxy_)
{
return comptrollerProxyToVaultProxy[_comptrollerProxy];
}
}
文件 3 的 11:FundDeployerOwnerMixin.sol
pragma solidity 0.6.12;
import "../../core/fund-deployer/IFundDeployer.sol";
abstract contract FundDeployerOwnerMixin {
address internal immutable FUND_DEPLOYER;
modifier onlyFundDeployerOwner() {
require(
msg.sender == getOwner(),
"onlyFundDeployerOwner: Only the FundDeployer owner can call this function"
);
_;
}
constructor(address _fundDeployer) public {
FUND_DEPLOYER = _fundDeployer;
}
function getOwner() public view returns (address owner_) {
return IFundDeployer(FUND_DEPLOYER).getOwner();
}
function getFundDeployer() external view returns (address fundDeployer_) {
return FUND_DEPLOYER;
}
}
文件 4 的 11:IComptroller.sol
pragma solidity 0.6.12;
interface IComptroller {
enum VaultAction {
None,
BurnShares,
MintShares,
TransferShares,
ApproveAssetSpender,
WithdrawAssetTo,
AddTrackedAsset,
RemoveTrackedAsset
}
function activate(address, bool) external;
function calcGav(bool) external returns (uint256, bool);
function calcGrossShareValue(bool) external returns (uint256, bool);
function callOnExtension(
address,
uint256,
bytes calldata
) external;
function configureExtensions(bytes calldata, bytes calldata) external;
function destruct() external;
function getDenominationAsset() external view returns (address);
function getVaultProxy() external view returns (address);
function init(address, uint256) external;
function permissionedVaultAction(VaultAction, bytes calldata) external;
}
文件 5 的 11:IExtension.sol
pragma solidity 0.6.12;
interface IExtension {
function activateForFund(bool _isMigration) external;
function deactivateForFund() external;
function receiveCallFromComptroller(
address _comptrollerProxy,
uint256 _actionId,
bytes calldata _callArgs
) external;
function setConfigForFund(bytes calldata _configData) external;
}
文件 6 的 11:IFundDeployer.sol
pragma solidity 0.6.12;
interface IFundDeployer {
enum ReleaseStatus {PreLaunch, Live, Paused}
function getOwner() external view returns (address);
function getReleaseStatus() external view returns (ReleaseStatus);
function isRegisteredVaultCall(address, bytes4) external view returns (bool);
}
文件 7 的 11:IMigratableVault.sol
pragma solidity 0.6.12;
interface IMigratableVault {
function canMigrate(address _who) external view returns (bool canMigrate_);
function init(
address _owner,
address _accessor,
string calldata _fundName
) external;
function setAccessor(address _nextAccessor) external;
function setVaultLib(address _nextVaultLib) external;
}
文件 8 的 11:IPolicy.sol
pragma solidity 0.6.12;
import "./IPolicyManager.sol";
interface IPolicy {
function activateForFund(address _comptrollerProxy, address _vaultProxy) external;
function addFundSettings(address _comptrollerProxy, bytes calldata _encodedSettings) external;
function identifier() external pure returns (string memory identifier_);
function implementedHooks()
external
view
returns (IPolicyManager.PolicyHook[] memory implementedHooks_);
function updateFundSettings(
address _comptrollerProxy,
address _vaultProxy,
bytes calldata _encodedSettings
) external;
function validateRule(
address _comptrollerProxy,
address _vaultProxy,
IPolicyManager.PolicyHook _hook,
bytes calldata _encodedArgs
) external returns (bool isValid_);
}
文件 9 的 11:IPolicyManager.sol
pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;
interface IPolicyManager {
enum PolicyHook {
BuySharesSetup,
PreBuyShares,
PostBuyShares,
BuySharesCompleted,
PreCallOnIntegration,
PostCallOnIntegration
}
function validatePolicies(
address,
PolicyHook,
bytes calldata
) external;
}
文件 10 的 11:IVault.sol
pragma solidity 0.6.12;
import "../../../../persistent/utils/IMigratableVault.sol";
interface IVault is IMigratableVault {
function addTrackedAsset(address) external;
function approveAssetSpender(
address,
address,
uint256
) external;
function burnShares(address, uint256) external;
function callOnContract(address, bytes calldata) external;
function getAccessor() external view returns (address);
function getOwner() external view returns (address);
function getTrackedAssets() external view returns (address[] memory);
function isTrackedAsset(address) external view returns (bool);
function mintShares(address, uint256) external;
function removeTrackedAsset(address) external;
function transferShares(
address,
address,
uint256
) external;
function withdrawAssetTo(
address,
address,
uint256
) external;
}
文件 11 的 11:PolicyManager.sol
pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;
import "@openzeppelin/contracts/utils/EnumerableSet.sol";
import "../../core/fund/vault/IVault.sol";
import "../utils/ExtensionBase.sol";
import "../utils/FundDeployerOwnerMixin.sol";
import "./IPolicy.sol";
import "./IPolicyManager.sol";
contract PolicyManager is IPolicyManager, ExtensionBase, FundDeployerOwnerMixin {
using EnumerableSet for EnumerableSet.AddressSet;
event PolicyDeregistered(address indexed policy, string indexed identifier);
event PolicyDisabledForFund(address indexed comptrollerProxy, address indexed policy);
event PolicyEnabledForFund(
address indexed comptrollerProxy,
address indexed policy,
bytes settingsData
);
event PolicyRegistered(
address indexed policy,
string indexed identifier,
PolicyHook[] implementedHooks
);
EnumerableSet.AddressSet private registeredPolicies;
mapping(address => mapping(PolicyHook => bool)) private policyToHookToIsImplemented;
mapping(address => EnumerableSet.AddressSet) private comptrollerProxyToPolicies;
modifier onlyBuySharesHooks(address _policy) {
require(
!policyImplementsHook(_policy, PolicyHook.PreCallOnIntegration) &&
!policyImplementsHook(_policy, PolicyHook.PostCallOnIntegration),
"onlyBuySharesHooks: Disallowed hook"
);
_;
}
modifier onlyEnabledPolicyForFund(address _comptrollerProxy, address _policy) {
require(
policyIsEnabledForFund(_comptrollerProxy, _policy),
"onlyEnabledPolicyForFund: Policy not enabled"
);
_;
}
constructor(address _fundDeployer) public FundDeployerOwnerMixin(_fundDeployer) {}
function activateForFund(bool _isMigratedFund) external override {
address vaultProxy = __setValidatedVaultProxy(msg.sender);
if (_isMigratedFund) {
address[] memory enabledPolicies = getEnabledPoliciesForFund(msg.sender);
for (uint256 i; i < enabledPolicies.length; i++) {
__activatePolicyForFund(msg.sender, vaultProxy, enabledPolicies[i]);
}
}
}
function deactivateForFund() external override {
delete comptrollerProxyToVaultProxy[msg.sender];
for (uint256 i = comptrollerProxyToPolicies[msg.sender].length(); i > 0; i--) {
comptrollerProxyToPolicies[msg.sender].remove(
comptrollerProxyToPolicies[msg.sender].at(i - 1)
);
}
}
function disablePolicyForFund(address _comptrollerProxy, address _policy)
external
onlyBuySharesHooks(_policy)
onlyEnabledPolicyForFund(_comptrollerProxy, _policy)
{
__validateIsFundOwner(getVaultProxyForFund(_comptrollerProxy), msg.sender);
comptrollerProxyToPolicies[_comptrollerProxy].remove(_policy);
emit PolicyDisabledForFund(_comptrollerProxy, _policy);
}
function enablePolicyForFund(
address _comptrollerProxy,
address _policy,
bytes calldata _settingsData
) external onlyBuySharesHooks(_policy) {
address vaultProxy = getVaultProxyForFund(_comptrollerProxy);
__validateIsFundOwner(vaultProxy, msg.sender);
__enablePolicyForFund(_comptrollerProxy, _policy, _settingsData);
__activatePolicyForFund(_comptrollerProxy, vaultProxy, _policy);
}
function setConfigForFund(bytes calldata _configData) external override {
(address[] memory policies, bytes[] memory settingsData) = abi.decode(
_configData,
(address[], bytes[])
);
require(
policies.length == settingsData.length,
"setConfigForFund: policies and settingsData array lengths unequal"
);
for (uint256 i; i < policies.length; i++) {
__enablePolicyForFund(msg.sender, policies[i], settingsData[i]);
}
}
function updatePolicySettingsForFund(
address _comptrollerProxy,
address _policy,
bytes calldata _settingsData
) external onlyBuySharesHooks(_policy) onlyEnabledPolicyForFund(_comptrollerProxy, _policy) {
address vaultProxy = getVaultProxyForFund(_comptrollerProxy);
__validateIsFundOwner(vaultProxy, msg.sender);
IPolicy(_policy).updateFundSettings(_comptrollerProxy, vaultProxy, _settingsData);
}
function validatePolicies(
address _comptrollerProxy,
PolicyHook _hook,
bytes calldata _validationData
) external override {
address vaultProxy = getVaultProxyForFund(_comptrollerProxy);
address[] memory policies = getEnabledPoliciesForFund(_comptrollerProxy);
for (uint256 i; i < policies.length; i++) {
if (!policyImplementsHook(policies[i], _hook)) {
continue;
}
require(
IPolicy(policies[i]).validateRule(
_comptrollerProxy,
vaultProxy,
_hook,
_validationData
),
string(
abi.encodePacked(
"Rule evaluated to false: ",
IPolicy(policies[i]).identifier()
)
)
);
}
}
function __activatePolicyForFund(
address _comptrollerProxy,
address _vaultProxy,
address _policy
) private {
IPolicy(_policy).activateForFund(_comptrollerProxy, _vaultProxy);
}
function __enablePolicyForFund(
address _comptrollerProxy,
address _policy,
bytes memory _settingsData
) private {
require(
!policyIsEnabledForFund(_comptrollerProxy, _policy),
"__enablePolicyForFund: policy already enabled"
);
require(policyIsRegistered(_policy), "__enablePolicyForFund: Policy is not registered");
if (_settingsData.length > 0) {
IPolicy(_policy).addFundSettings(_comptrollerProxy, _settingsData);
}
comptrollerProxyToPolicies[_comptrollerProxy].add(_policy);
emit PolicyEnabledForFund(_comptrollerProxy, _policy, _settingsData);
}
function __validateIsFundOwner(address _vaultProxy, address _who) private view {
require(
_who == IVault(_vaultProxy).getOwner(),
"Only the fund owner can call this function"
);
}
function deregisterPolicies(address[] calldata _policies) external onlyFundDeployerOwner {
require(_policies.length > 0, "deregisterPolicies: _policies cannot be empty");
for (uint256 i; i < _policies.length; i++) {
require(
policyIsRegistered(_policies[i]),
"deregisterPolicies: policy is not registered"
);
registeredPolicies.remove(_policies[i]);
emit PolicyDeregistered(_policies[i], IPolicy(_policies[i]).identifier());
}
}
function registerPolicies(address[] calldata _policies) external onlyFundDeployerOwner {
require(_policies.length > 0, "registerPolicies: _policies cannot be empty");
for (uint256 i; i < _policies.length; i++) {
require(
!policyIsRegistered(_policies[i]),
"registerPolicies: policy already registered"
);
registeredPolicies.add(_policies[i]);
IPolicy policyContract = IPolicy(_policies[i]);
PolicyHook[] memory implementedHooks = policyContract.implementedHooks();
for (uint256 j; j < implementedHooks.length; j++) {
policyToHookToIsImplemented[_policies[i]][implementedHooks[j]] = true;
}
emit PolicyRegistered(_policies[i], policyContract.identifier(), implementedHooks);
}
}
function getRegisteredPolicies()
external
view
returns (address[] memory registeredPoliciesArray_)
{
registeredPoliciesArray_ = new address[](registeredPolicies.length());
for (uint256 i; i < registeredPoliciesArray_.length; i++) {
registeredPoliciesArray_[i] = registeredPolicies.at(i);
}
}
function getEnabledPoliciesForFund(address _comptrollerProxy)
public
view
returns (address[] memory enabledPolicies_)
{
enabledPolicies_ = new address[](comptrollerProxyToPolicies[_comptrollerProxy].length());
for (uint256 i; i < enabledPolicies_.length; i++) {
enabledPolicies_[i] = comptrollerProxyToPolicies[_comptrollerProxy].at(i);
}
}
function policyImplementsHook(address _policy, PolicyHook _hook)
public
view
returns (bool implementsHook_)
{
return policyToHookToIsImplemented[_policy][_hook];
}
function policyIsEnabledForFund(address _comptrollerProxy, address _policy)
public
view
returns (bool isEnabled_)
{
return comptrollerProxyToPolicies[_comptrollerProxy].contains(_policy);
}
function policyIsRegistered(address _policy) public view returns (bool isRegistered_) {
return registeredPolicies.contains(_policy);
}
}
{
"compilationTarget": {
"contracts/release/extensions/policy-manager/PolicyManager.sol": "PolicyManager"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"details": {
"constantOptimizer": true,
"cse": true,
"deduplicate": true,
"jumpdestRemover": true,
"orderLiterals": true,
"peephole": true,
"yul": false
},
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_fundDeployer","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"policy","type":"address"},{"indexed":true,"internalType":"string","name":"identifier","type":"string"}],"name":"PolicyDeregistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"comptrollerProxy","type":"address"},{"indexed":true,"internalType":"address","name":"policy","type":"address"}],"name":"PolicyDisabledForFund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"comptrollerProxy","type":"address"},{"indexed":true,"internalType":"address","name":"policy","type":"address"},{"indexed":false,"internalType":"bytes","name":"settingsData","type":"bytes"}],"name":"PolicyEnabledForFund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"policy","type":"address"},{"indexed":true,"internalType":"string","name":"identifier","type":"string"},{"indexed":false,"internalType":"enum IPolicyManager.PolicyHook[]","name":"implementedHooks","type":"uint8[]"}],"name":"PolicyRegistered","type":"event"},{"inputs":[{"internalType":"bool","name":"_isMigratedFund","type":"bool"}],"name":"activateForFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deactivateForFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_policies","type":"address[]"}],"name":"deregisterPolicies","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_comptrollerProxy","type":"address"},{"internalType":"address","name":"_policy","type":"address"}],"name":"disablePolicyForFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_comptrollerProxy","type":"address"},{"internalType":"address","name":"_policy","type":"address"},{"internalType":"bytes","name":"_settingsData","type":"bytes"}],"name":"enablePolicyForFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_comptrollerProxy","type":"address"}],"name":"getEnabledPoliciesForFund","outputs":[{"internalType":"address[]","name":"enabledPolicies_","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFundDeployer","outputs":[{"internalType":"address","name":"fundDeployer_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"owner_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRegisteredPolicies","outputs":[{"internalType":"address[]","name":"registeredPoliciesArray_","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_comptrollerProxy","type":"address"}],"name":"getVaultProxyForFund","outputs":[{"internalType":"address","name":"vaultProxy_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_policy","type":"address"},{"internalType":"enum IPolicyManager.PolicyHook","name":"_hook","type":"uint8"}],"name":"policyImplementsHook","outputs":[{"internalType":"bool","name":"implementsHook_","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_comptrollerProxy","type":"address"},{"internalType":"address","name":"_policy","type":"address"}],"name":"policyIsEnabledForFund","outputs":[{"internalType":"bool","name":"isEnabled_","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_policy","type":"address"}],"name":"policyIsRegistered","outputs":[{"internalType":"bool","name":"isRegistered_","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"receiveCallFromComptroller","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_policies","type":"address[]"}],"name":"registerPolicies","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_configData","type":"bytes"}],"name":"setConfigForFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_comptrollerProxy","type":"address"},{"internalType":"address","name":"_policy","type":"address"},{"internalType":"bytes","name":"_settingsData","type":"bytes"}],"name":"updatePolicySettingsForFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_comptrollerProxy","type":"address"},{"internalType":"enum IPolicyManager.PolicyHook","name":"_hook","type":"uint8"},{"internalType":"bytes","name":"_validationData","type":"bytes"}],"name":"validatePolicies","outputs":[],"stateMutability":"nonpayable","type":"function"}]