pragma solidity ^0.4.18; import "./Avatar.sol"; import "./Reputation.sol"; import "./DAOToken.sol"; import "../globalConstraints/GlobalConstraintInterface.sol"; import "./ControllerInterface.sol"; /** * @title Universal Controller contract * @dev A universal controller hold organizations and controls their tokens ,reputations * and avatar. * It is subject to a set of schemes and constraints that determine its behavior. * Each scheme has it own parameters and operation permissions. */ contract UController is ControllerInterface { struct Scheme { bytes32 paramsHash; // a hash "configuration" of the scheme bytes4 permissions; // A bitwise flags of permissions, // All 0: Not registered, // 1st bit: Flag if the scheme is registered, // 2nd bit: Scheme can register other schemes // 3th bit: Scheme can add/remove global constraints // 4rd bit: Scheme can upgrade the controller } struct GlobalConstraint { address gcAddress; bytes32 params; } struct GlobalConstraintRegister { bool register; //is register uint index; //index at globalConstraints } struct Organization { DAOToken nativeToken; Reputation nativeReputation; mapping(address=>Scheme) schemes; // globalConstraints that determine pre- and post-conditions for all actions on the controller GlobalConstraint[] globalConstraints; // globalConstraintsRegister indicate is a globalConstraints is register or not mapping(address=>GlobalConstraintRegister) globalConstraintsRegister; bool exist; } //mapping between organization's avatar address to Organization mapping(address=>Organization) organizations; // newController will point to the new controller after the present controller is upgraded // address public newController; mapping(address=>address) public newControllers;//mapping between avatar address and newController address event MintReputation (address indexed _sender, address indexed _beneficiary, int256 _amount,address indexed _avatar); event MintTokens (address indexed _sender, address indexed _beneficiary, uint256 _amount, address indexed _avatar); event RegisterScheme (address indexed _sender, address indexed _scheme,address indexed _avatar); event UnregisterScheme (address indexed _sender, address indexed _scheme, address indexed _avatar); event GenericAction (address indexed _sender, bytes32[] _params); event SendEther (address indexed _sender, uint _amountInWei, address indexed _to); event ExternalTokenTransfer (address indexed _sender, address indexed _externalToken, address indexed _to, uint _value); event ExternalTokenTransferFrom (address indexed _sender, address indexed _externalToken, address _from, address _to, uint _value); event ExternalTokenIncreaseApproval (address indexed _sender, StandardToken indexed _externalToken, address _spender, uint _value); event ExternalTokenDecreaseApproval (address indexed _sender, StandardToken indexed _externalToken, address _spender, uint _value); event AddGlobalConstraint(address _globalConstraint, bytes32 _params); event RemoveGlobalConstraint(address _globalConstraint ,uint256 _index); event UpgradeController(address _oldController,address _newController,address _avatar); function UController()public {} /** * @dev newOrganization set up a new organization with default daoCreator. * @param _avatar the organization avatar */ function newOrganization( Avatar _avatar ) public { require(!organizations[address(_avatar)].exist); require(_avatar.owner() == address(this)); organizations[address(_avatar)].exist = true; organizations[address(_avatar)].nativeToken = _avatar.nativeToken(); organizations[address(_avatar)].nativeReputation = _avatar.nativeReputation(); organizations[address(_avatar)].schemes[msg.sender] = Scheme({paramsHash: bytes32(0),permissions: bytes4(0xF)}); RegisterScheme(msg.sender, msg.sender,_avatar); } // Modifiers: modifier onlyRegisteredScheme(address avatar) { require(organizations[avatar].schemes[msg.sender].permissions&bytes4(1) == bytes4(1)); _; } modifier onlyRegisteringSchemes(address avatar) { require(organizations[avatar].schemes[msg.sender].permissions&bytes4(2) == bytes4(2)); _; } modifier onlyGlobalConstraintsScheme(address avatar) { require(organizations[avatar].schemes[msg.sender].permissions&bytes4(4) == bytes4(4)); _; } modifier onlyUpgradingScheme(address _avatar) { require(organizations[_avatar].schemes[msg.sender].permissions&bytes4(8) == bytes4(8)); _; } modifier onlySubjectToConstraint(bytes32 func,address _avatar) { uint index; GlobalConstraint[] memory globalConstraints = organizations[_avatar].globalConstraints; for (index = 0;index