2018-01-25 16:31:13 +00:00
|
|
|
pragma solidity ^0.4.18;
|
|
|
|
|
|
|
|
/*
|
|
|
|
Copyright 2017, Jordi Baylina, RJ Ewing
|
|
|
|
Contributors: Adrià Massanet <adria@codecontext.io>, Griff Green,
|
|
|
|
Arthur Lunn
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2018-02-10 14:14:52 +00:00
|
|
|
import "@aragon/os/contracts/apps/AragonApp.sol";
|
2018-02-13 18:56:11 +00:00
|
|
|
import "./LiquidPledgingStorage.sol";
|
2018-02-20 16:12:01 +00:00
|
|
|
import "./LiquidPledgingACLHelpers.sol";
|
2018-01-25 16:31:13 +00:00
|
|
|
|
2018-02-20 16:12:01 +00:00
|
|
|
contract LiquidPledgingPlugins is AragonApp, LiquidPledgingStorage, LiquidPledgingACLHelpers {
|
2018-02-10 14:14:52 +00:00
|
|
|
|
|
|
|
bytes32 constant public PLUGIN_MANAGER_ROLE = keccak256("PLUGIN_MANAGER_ROLE");
|
2018-01-25 16:31:13 +00:00
|
|
|
|
2018-06-16 00:27:47 +00:00
|
|
|
/**
|
|
|
|
* @dev adds an instance of a plugin to the whitelist
|
|
|
|
*/
|
2018-03-27 17:55:37 +00:00
|
|
|
function addValidPluginInstance(address addr) auth(PLUGIN_MANAGER_ROLE) external {
|
2018-02-24 15:36:09 +00:00
|
|
|
pluginInstanceWhitelist[addr] = true;
|
2018-01-25 16:31:13 +00:00
|
|
|
}
|
|
|
|
|
2018-06-16 00:27:47 +00:00
|
|
|
/**
|
|
|
|
* @dev add a contract to the plugin whitelist.
|
|
|
|
* @notice Proxy contracts should never be added using this method. Each individual
|
|
|
|
* proxy instance should be added by calling `addValidPluginInstance`
|
|
|
|
*/
|
2018-02-24 15:36:09 +00:00
|
|
|
function addValidPluginContract(bytes32 contractHash) auth(PLUGIN_MANAGER_ROLE) public {
|
|
|
|
pluginContractWhitelist[contractHash] = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
function addValidPluginContracts(bytes32[] contractHashes) external auth(PLUGIN_MANAGER_ROLE) {
|
2018-01-25 23:11:07 +00:00
|
|
|
for (uint8 i = 0; i < contractHashes.length; i++) {
|
2018-02-24 15:36:09 +00:00
|
|
|
addValidPluginContract(contractHashes[i]);
|
2018-01-25 16:31:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-16 00:27:47 +00:00
|
|
|
/**
|
|
|
|
* @dev removes a contract from the plugin whitelist
|
|
|
|
*/
|
2018-02-24 15:36:09 +00:00
|
|
|
function removeValidPluginContract(bytes32 contractHash) external authP(PLUGIN_MANAGER_ROLE, arr(contractHash)) {
|
|
|
|
pluginContractWhitelist[contractHash] = false;
|
|
|
|
}
|
|
|
|
|
2018-06-16 00:27:47 +00:00
|
|
|
/**
|
|
|
|
* @dev removes an instance of a plugin to the whitelist
|
|
|
|
*/
|
2018-03-27 17:55:37 +00:00
|
|
|
function removeValidPluginInstance(address addr) external authP(PLUGIN_MANAGER_ROLE, arr(addr)) {
|
2018-02-24 15:36:09 +00:00
|
|
|
pluginInstanceWhitelist[addr] = false;
|
2018-01-25 16:31:13 +00:00
|
|
|
}
|
|
|
|
|
2018-06-16 00:27:47 +00:00
|
|
|
/**
|
|
|
|
* @dev enable/disable the plugin whitelist.
|
|
|
|
* @notice you better know what you're doing if you are going to disable it
|
|
|
|
*/
|
2018-02-20 17:38:13 +00:00
|
|
|
function useWhitelist(bool useWhitelist) external auth(PLUGIN_MANAGER_ROLE) {
|
2018-01-25 16:31:13 +00:00
|
|
|
whitelistDisabled = !useWhitelist;
|
|
|
|
}
|
|
|
|
|
2018-06-16 00:27:47 +00:00
|
|
|
/**
|
|
|
|
* check if the contract at the provided address is in the plugin whitelist
|
|
|
|
*/
|
2018-01-25 16:31:13 +00:00
|
|
|
function isValidPlugin(address addr) public view returns(bool) {
|
|
|
|
if (whitelistDisabled || addr == 0x0) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-02-24 15:36:09 +00:00
|
|
|
// first check pluginInstances
|
|
|
|
if (pluginInstanceWhitelist[addr]) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if the addr isn't a valid instance, check the contract code
|
2018-01-25 16:31:13 +00:00
|
|
|
bytes32 contractHash = getCodeHash(addr);
|
|
|
|
|
2018-02-24 15:36:09 +00:00
|
|
|
return pluginContractWhitelist[contractHash];
|
2018-01-25 16:31:13 +00:00
|
|
|
}
|
|
|
|
|
2018-06-16 00:27:47 +00:00
|
|
|
/**
|
|
|
|
* @return the hash of the code for the given address
|
|
|
|
*/
|
2018-01-25 16:31:13 +00:00
|
|
|
function getCodeHash(address addr) public view returns(bytes32) {
|
|
|
|
bytes memory o_code;
|
|
|
|
assembly {
|
2018-06-21 17:40:30 +00:00
|
|
|
// retrieve the size of the code
|
2018-01-25 16:31:13 +00:00
|
|
|
let size := extcodesize(addr)
|
2018-06-21 17:40:30 +00:00
|
|
|
// allocate output byte array
|
2018-01-25 16:31:13 +00:00
|
|
|
o_code := mload(0x40)
|
2018-02-16 01:33:04 +00:00
|
|
|
mstore(o_code, size) // store length in memory
|
2018-06-21 17:40:30 +00:00
|
|
|
// actually retrieve the code
|
2018-01-25 16:31:13 +00:00
|
|
|
extcodecopy(addr, add(o_code, 0x20), 0, size)
|
|
|
|
}
|
|
|
|
return keccak256(o_code);
|
|
|
|
}
|
|
|
|
}
|