diff --git a/packages/ap-contracts/build/contracts/SimpleRestrictedRuleEngine.json b/packages/ap-contracts/build/contracts/SimpleRestrictedRuleEngine.json new file mode 100644 index 00000000..ef485e3b --- /dev/null +++ b/packages/ap-contracts/build/contracts/SimpleRestrictedRuleEngine.json @@ -0,0 +1,604 @@ +{ + "contractName": "SimpleRestrictedRuleEngine", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "addedAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint8", + "name": "whitelist", + "type": "uint8" + }, + { + "indexed": true, + "internalType": "address", + "name": "addedBy", + "type": "address" + } + ], + "name": "AddressAddedToWhitelist", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "removedAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint8", + "name": "whitelist", + "type": "uint8" + }, + { + "indexed": true, + "internalType": "address", + "name": "removedBy", + "type": "address" + } + ], + "name": "AddressRemovedFromWhitelist", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "addedAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "addedBy", + "type": "address" + } + ], + "name": "AdminAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "removedAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "removedBy", + "type": "address" + } + ], + "name": "AdminRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "updatedBy", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint8", + "name": "sourceWhitelist", + "type": "uint8" + }, + { + "indexed": true, + "internalType": "uint8", + "name": "destinationWhitelist", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "bool", + "name": "from", + "type": "bool" + }, + { + "indexed": false, + "internalType": "bool", + "name": "to", + "type": "bool" + } + ], + "name": "OutboundWhitelistUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "RestrictionsDisabled", + "type": "event" + }, + { + "inputs": [], + "name": "FAILURE_NON_WHITELIST", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FAILURE_NON_WHITELIST_MESSAGE", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SUCCESS_CODE", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SUCCESS_MESSAGE", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UNKNOWN_ERROR", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "adminToAdd", + "type": "address" + } + ], + "name": "addAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addressToAdd", + "type": "address" + }, + { + "internalType": "uint8", + "name": "whitelist", + "type": "uint8" + } + ], + "name": "addToWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "addressWhitelists", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "administrators", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "checkWhitelistAllowed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "detectTransferRestriction", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "disableRestrictions", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addressToTest", + "type": "address" + } + ], + "name": "isAdministrator", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isRestrictionEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "restrictionCode", + "type": "uint8" + } + ], + "name": "messageForTransferRestriction", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "name": "outboundWhitelistsEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "adminToRemove", + "type": "address" + } + ], + "name": "removeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "addressToRemove", + "type": "address" + } + ], + "name": "removeFromWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "ruleId", + "type": "uint256" + } + ], + "name": "rule", + "outputs": [ + { + "internalType": "contract IRule", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ruleLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rules", + "outputs": [ + { + "internalType": "contract IRule[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IRule[]", + "name": "rules", + "type": "address[]" + } + ], + "name": "setRules", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "sourceWhitelist", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "destinationWhitelist", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "newEnabledValue", + "type": "bool" + } + ], + "name": "updateOutboundWhitelistEnabled", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "validateTransfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x6080604052609a805460ff1916600117905534801561001d57600080fd5b506111a28061002d6000396000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c80638da5cb5b116100f9578063c893446211610097578063dce306ad11610071578063dce306ad146105a1578063e7984d17146105a9578063e9594508146105b1578063f2fde38b146105d9576101a9565b8063c893446214610546578063d4ce14151461054e578063db18af6c14610584576101a9565b806397af6744116100d357806397af67441461047e578063b27aef3a14610486578063b4627416146104f6578063c6946a1214610510576101a9565b80638da5cb5b1461040657806392e6d68b1461042a5780639437e2fe14610450576101a9565b80633973b59611610166578063715018a611610140578063715018a61461031d57806376be1585146103255780637f4ab1dd1461034b5780638ab1d681146103e0576101a9565b80633973b5961461026d57806352f6747a1461029f57806370480275146102f7576101a9565b80630263b858146101ae5780630a2eb301146101df5780630e969a05146102195780631785f53c146102375780631fb45ec01461025d5780632a64240714610265575b600080fd5b6101dd600480360360408110156101c457600080fd5b5080356001600160a01b0316906020013560ff166105ff565b005b610205600480360360208110156101f557600080fd5b50356001600160a01b0316610743565b604080519115158252519081900360200190f35b610221610765565b6040805160ff9092168252519081900360200190f35b6101dd6004803603602081101561024d57600080fd5b50356001600160a01b031661076a565b610221610869565b61020561086e565b6101dd6004803603606081101561028357600080fd5b5060ff8135811691602081013590911690604001351515610877565b6102a7610934565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156102e35781810151838201526020016102cb565b505050509050019250505060405180910390f35b6101dd6004803603602081101561030d57600080fd5b50356001600160a01b0316610939565b6101dd610a37565b6102056004803603602081101561033b57600080fd5b50356001600160a01b0316610ad9565b61036b6004803603602081101561036157600080fd5b503560ff16610aee565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103a557818101518382015260200161038d565b50505050905090810190601f1680156103d25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101dd600480360360208110156103f657600080fd5b50356001600160a01b0316610b76565b61040e610c11565b604080516001600160a01b039092168252519081900360200190f35b6102216004803603602081101561044057600080fd5b50356001600160a01b0316610c20565b6102056004803603604081101561046657600080fd5b506001600160a01b0381358116916020013516610c35565b61036b610ca9565b6101dd6004803603602081101561049c57600080fd5b8101906020810181356401000000008111156104b757600080fd5b8201836020820111156104c957600080fd5b803590602001918460208302840111640100000000831117156104eb57600080fd5b509092509050610cd7565b6104fe610d7c565b60408051918252519081900360200190f35b6102056004803603606081101561052657600080fd5b506001600160a01b03813581169160208101359091169060400135610d81565b61036b610d9d565b6102216004803603606081101561056457600080fd5b506001600160a01b03813581169160208101359091169060400135610db9565b61040e6004803603602081101561059a57600080fd5b5035610e18565b6101dd610e1e565b61036b610eee565b610205600480360360408110156105c757600080fd5b5060ff81358116916020013516610f11565b6101dd600480360360208110156105ef57600080fd5b50356001600160a01b0316610f31565b61060833610743565b6106435760405162461bcd60e51b81526004018080602001828103825260288152602001806110926028913960400191505060405180910390fd5b60ff8116610698576040805162461bcd60e51b815260206004820152601d60248201527f496e76616c69642077686974656c69737420494420737570706c696564000000604482015290519081900360640190fd5b6001600160a01b0382166000908152609860205260409020805460ff83811660ff1983161790925516801561070357604051339060ff8316906001600160a01b038616907fb50a30a0fa972f89fbb2b514d12b31f5a5d64f53603402de7939742cd8507f6e90600090a45b604051339060ff8416906001600160a01b038616907fca6d1e885708b837a7647aeb7f4163ee4ca96058e08ac767be8d23c972c5027090600090a4505050565b6001600160a01b03811660009081526097602052604090205460ff165b919050565b600081565b61077261102a565b6065546001600160a01b039081169116146107c2576040805162461bcd60e51b815260206004820181905260248201526000805160206110ba833981519152604482015290519081900360640190fd5b6001600160a01b03811660009081526097602052604090205460ff16151560011461081e5760405162461bcd60e51b815260040180806020018281038252603d815260200180611055603d913960400191505060405180910390fd5b6001600160a01b038116600081815260976020526040808220805460ff19169055513392917fdb9d5d31320daf5bc7181d565b6da4d12e30f0f4d5aa324a992426c14a1d19ce91a350565b600181565b609a5460ff1690565b61088033610743565b6108bb5760405162461bcd60e51b81526004018080602001828103825260288152602001806110926028913960400191505060405180910390fd5b60ff838116600081815260996020908152604080832087861680855290835292819020805487151560ff1982168117909255825196168015158752928601528051919492939233927fb0353d563a9aa5231878c83727dc723a3cb8a38c2917f8ac2b777aa564c8a0d5929181900390910190a450505050565b606090565b61094161102a565b6065546001600160a01b03908116911614610991576040805162461bcd60e51b815260206004820181905260248201526000805160206110ba833981519152604482015290519081900360640190fd5b6001600160a01b03811660009081526097602052604090205460ff16156109e95760405162461bcd60e51b81526004018080602001828103825260358152602001806111386035913960400191505060405180910390fd5b6001600160a01b038116600081815260976020526040808220805460ff19166001179055513392917fbf3f493c772c8c283fd124432c2d0f539ab343faa04258fe88e52912d36b102b91a350565b610a3f61102a565b6065546001600160a01b03908116911614610a8f576040805162461bcd60e51b815260206004820181905260248201526000805160206110ba833981519152604482015290519081900360640190fd5b6065546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3606580546001600160a01b0319169055565b60976020526000908152604090205460ff1681565b606060ff8216610b1c57506040805180820190915260078152665355434345535360c81b6020820152610760565b60ff821660011415610b48576040518060600160405280603c81526020016110fc603c91399050610760565b5050604080518082019091526012815271556e6b6e6f776e204572726f7220436f646560701b602082015290565b610b7f33610743565b610bba5760405162461bcd60e51b81526004018080602001828103825260288152602001806110926028913960400191505060405180910390fd5b6001600160a01b038116600081815260986020526040808220805460ff198116909155905160ff90911692339284927fb50a30a0fa972f89fbb2b514d12b31f5a5d64f53603402de7939742cd8507f6e9190a45050565b6065546001600160a01b031690565b60986020526000908152604090205460ff1681565b6001600160a01b03808316600090815260986020526040808220549284168252812054909160ff9081169116811580610c6f575060ff8116155b15610c7f57600092505050610ca3565b60ff9182166000908152609960209081526040808320938516835292905220541690505b92915050565b60405180604001604052806012815260200171556e6b6e6f776e204572726f7220436f646560701b81525081565b610cdf61102a565b6065546001600160a01b03908116911614610d2f576040805162461bcd60e51b815260206004820181905260248201526000805160206110ba833981519152604482015290519081900360640190fd5b6040805162461bcd60e51b815260206004820181905260248201527f43616e206e6f742073657420616e79206164646974696f6e616c2072756c6573604482015290519081900360640190fd5b600090565b600080610d8f858585610db9565b60ff161490505b9392505050565b6040518060600160405280603c81526020016110fc603c913981565b6000610dc361086e565b610dcf57506000610d96565b610dd7610c11565b6001600160a01b0316846001600160a01b03161415610df857506000610d96565b610e028484610c35565b610e0e57506001610d96565b5060009392505050565b50600090565b610e2661102a565b6065546001600160a01b03908116911614610e76576040805162461bcd60e51b815260206004820181905260248201526000805160206110ba833981519152604482015290519081900360640190fd5b609a5460ff16610eb75760405162461bcd60e51b81526004018080602001828103825260228152602001806110da6022913960400191505060405180910390fd5b609a805460ff1916905560405133907f3c13a557aa89734e312c348465096b4ddc97709822675c45090f4e2a8d6c4f2b90600090a2565b604051806040016040528060078152602001665355434345535360c81b81525081565b609960209081526000928352604080842090915290825290205460ff1681565b610f3961102a565b6065546001600160a01b03908116911614610f89576040805162461bcd60e51b815260206004820181905260248201526000805160206110ba833981519152604482015290519081900360640190fd5b6001600160a01b038116610fce5760405162461bcd60e51b815260040180806020018281038252602681526020018061102f6026913960400191505060405180910390fd5b6065546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3606580546001600160a01b0319166001600160a01b0392909216919091179055565b339056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734163636f756e7420746f2062652072656d6f7665642066726f6d2061646d696e206c697374206973206e6f7420616c726561647920616e2061646d696e43616c6c696e67206163636f756e74206973206e6f7420616e2061646d696e6973747261746f722e4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725265737472696374696f6e732061726520616c72656164792064697361626c65642e546865207472616e736665722077617320726573747269637465642064756520746f207768697465206c69737420636f6e66696775726174696f6e2e4163636f756e7420746f20626520616464656420746f2061646d696e206c69737420697320616c726561647920616e2061646d696ea264697066735822122072ce0463649757ac84902cc940c137577b7165ef329f2fbbc0e7f26ec3aba32464736f6c634300060b0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101a95760003560e01c80638da5cb5b116100f9578063c893446211610097578063dce306ad11610071578063dce306ad146105a1578063e7984d17146105a9578063e9594508146105b1578063f2fde38b146105d9576101a9565b8063c893446214610546578063d4ce14151461054e578063db18af6c14610584576101a9565b806397af6744116100d357806397af67441461047e578063b27aef3a14610486578063b4627416146104f6578063c6946a1214610510576101a9565b80638da5cb5b1461040657806392e6d68b1461042a5780639437e2fe14610450576101a9565b80633973b59611610166578063715018a611610140578063715018a61461031d57806376be1585146103255780637f4ab1dd1461034b5780638ab1d681146103e0576101a9565b80633973b5961461026d57806352f6747a1461029f57806370480275146102f7576101a9565b80630263b858146101ae5780630a2eb301146101df5780630e969a05146102195780631785f53c146102375780631fb45ec01461025d5780632a64240714610265575b600080fd5b6101dd600480360360408110156101c457600080fd5b5080356001600160a01b0316906020013560ff166105ff565b005b610205600480360360208110156101f557600080fd5b50356001600160a01b0316610743565b604080519115158252519081900360200190f35b610221610765565b6040805160ff9092168252519081900360200190f35b6101dd6004803603602081101561024d57600080fd5b50356001600160a01b031661076a565b610221610869565b61020561086e565b6101dd6004803603606081101561028357600080fd5b5060ff8135811691602081013590911690604001351515610877565b6102a7610934565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156102e35781810151838201526020016102cb565b505050509050019250505060405180910390f35b6101dd6004803603602081101561030d57600080fd5b50356001600160a01b0316610939565b6101dd610a37565b6102056004803603602081101561033b57600080fd5b50356001600160a01b0316610ad9565b61036b6004803603602081101561036157600080fd5b503560ff16610aee565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103a557818101518382015260200161038d565b50505050905090810190601f1680156103d25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101dd600480360360208110156103f657600080fd5b50356001600160a01b0316610b76565b61040e610c11565b604080516001600160a01b039092168252519081900360200190f35b6102216004803603602081101561044057600080fd5b50356001600160a01b0316610c20565b6102056004803603604081101561046657600080fd5b506001600160a01b0381358116916020013516610c35565b61036b610ca9565b6101dd6004803603602081101561049c57600080fd5b8101906020810181356401000000008111156104b757600080fd5b8201836020820111156104c957600080fd5b803590602001918460208302840111640100000000831117156104eb57600080fd5b509092509050610cd7565b6104fe610d7c565b60408051918252519081900360200190f35b6102056004803603606081101561052657600080fd5b506001600160a01b03813581169160208101359091169060400135610d81565b61036b610d9d565b6102216004803603606081101561056457600080fd5b506001600160a01b03813581169160208101359091169060400135610db9565b61040e6004803603602081101561059a57600080fd5b5035610e18565b6101dd610e1e565b61036b610eee565b610205600480360360408110156105c757600080fd5b5060ff81358116916020013516610f11565b6101dd600480360360208110156105ef57600080fd5b50356001600160a01b0316610f31565b61060833610743565b6106435760405162461bcd60e51b81526004018080602001828103825260288152602001806110926028913960400191505060405180910390fd5b60ff8116610698576040805162461bcd60e51b815260206004820152601d60248201527f496e76616c69642077686974656c69737420494420737570706c696564000000604482015290519081900360640190fd5b6001600160a01b0382166000908152609860205260409020805460ff83811660ff1983161790925516801561070357604051339060ff8316906001600160a01b038616907fb50a30a0fa972f89fbb2b514d12b31f5a5d64f53603402de7939742cd8507f6e90600090a45b604051339060ff8416906001600160a01b038616907fca6d1e885708b837a7647aeb7f4163ee4ca96058e08ac767be8d23c972c5027090600090a4505050565b6001600160a01b03811660009081526097602052604090205460ff165b919050565b600081565b61077261102a565b6065546001600160a01b039081169116146107c2576040805162461bcd60e51b815260206004820181905260248201526000805160206110ba833981519152604482015290519081900360640190fd5b6001600160a01b03811660009081526097602052604090205460ff16151560011461081e5760405162461bcd60e51b815260040180806020018281038252603d815260200180611055603d913960400191505060405180910390fd5b6001600160a01b038116600081815260976020526040808220805460ff19169055513392917fdb9d5d31320daf5bc7181d565b6da4d12e30f0f4d5aa324a992426c14a1d19ce91a350565b600181565b609a5460ff1690565b61088033610743565b6108bb5760405162461bcd60e51b81526004018080602001828103825260288152602001806110926028913960400191505060405180910390fd5b60ff838116600081815260996020908152604080832087861680855290835292819020805487151560ff1982168117909255825196168015158752928601528051919492939233927fb0353d563a9aa5231878c83727dc723a3cb8a38c2917f8ac2b777aa564c8a0d5929181900390910190a450505050565b606090565b61094161102a565b6065546001600160a01b03908116911614610991576040805162461bcd60e51b815260206004820181905260248201526000805160206110ba833981519152604482015290519081900360640190fd5b6001600160a01b03811660009081526097602052604090205460ff16156109e95760405162461bcd60e51b81526004018080602001828103825260358152602001806111386035913960400191505060405180910390fd5b6001600160a01b038116600081815260976020526040808220805460ff19166001179055513392917fbf3f493c772c8c283fd124432c2d0f539ab343faa04258fe88e52912d36b102b91a350565b610a3f61102a565b6065546001600160a01b03908116911614610a8f576040805162461bcd60e51b815260206004820181905260248201526000805160206110ba833981519152604482015290519081900360640190fd5b6065546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3606580546001600160a01b0319169055565b60976020526000908152604090205460ff1681565b606060ff8216610b1c57506040805180820190915260078152665355434345535360c81b6020820152610760565b60ff821660011415610b48576040518060600160405280603c81526020016110fc603c91399050610760565b5050604080518082019091526012815271556e6b6e6f776e204572726f7220436f646560701b602082015290565b610b7f33610743565b610bba5760405162461bcd60e51b81526004018080602001828103825260288152602001806110926028913960400191505060405180910390fd5b6001600160a01b038116600081815260986020526040808220805460ff198116909155905160ff90911692339284927fb50a30a0fa972f89fbb2b514d12b31f5a5d64f53603402de7939742cd8507f6e9190a45050565b6065546001600160a01b031690565b60986020526000908152604090205460ff1681565b6001600160a01b03808316600090815260986020526040808220549284168252812054909160ff9081169116811580610c6f575060ff8116155b15610c7f57600092505050610ca3565b60ff9182166000908152609960209081526040808320938516835292905220541690505b92915050565b60405180604001604052806012815260200171556e6b6e6f776e204572726f7220436f646560701b81525081565b610cdf61102a565b6065546001600160a01b03908116911614610d2f576040805162461bcd60e51b815260206004820181905260248201526000805160206110ba833981519152604482015290519081900360640190fd5b6040805162461bcd60e51b815260206004820181905260248201527f43616e206e6f742073657420616e79206164646974696f6e616c2072756c6573604482015290519081900360640190fd5b600090565b600080610d8f858585610db9565b60ff161490505b9392505050565b6040518060600160405280603c81526020016110fc603c913981565b6000610dc361086e565b610dcf57506000610d96565b610dd7610c11565b6001600160a01b0316846001600160a01b03161415610df857506000610d96565b610e028484610c35565b610e0e57506001610d96565b5060009392505050565b50600090565b610e2661102a565b6065546001600160a01b03908116911614610e76576040805162461bcd60e51b815260206004820181905260248201526000805160206110ba833981519152604482015290519081900360640190fd5b609a5460ff16610eb75760405162461bcd60e51b81526004018080602001828103825260228152602001806110da6022913960400191505060405180910390fd5b609a805460ff1916905560405133907f3c13a557aa89734e312c348465096b4ddc97709822675c45090f4e2a8d6c4f2b90600090a2565b604051806040016040528060078152602001665355434345535360c81b81525081565b609960209081526000928352604080842090915290825290205460ff1681565b610f3961102a565b6065546001600160a01b03908116911614610f89576040805162461bcd60e51b815260206004820181905260248201526000805160206110ba833981519152604482015290519081900360640190fd5b6001600160a01b038116610fce5760405162461bcd60e51b815260040180806020018281038252602681526020018061102f6026913960400191505060405180910390fd5b6065546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3606580546001600160a01b0319166001600160a01b0392909216919091179055565b339056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734163636f756e7420746f2062652072656d6f7665642066726f6d2061646d696e206c697374206973206e6f7420616c726561647920616e2061646d696e43616c6c696e67206163636f756e74206973206e6f7420616e2061646d696e6973747261746f722e4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725265737472696374696f6e732061726520616c72656164792064697361626c65642e546865207472616e736665722077617320726573747269637465642064756520746f207768697465206c69737420636f6e66696775726174696f6e2e4163636f756e7420746f20626520616464656420746f2061646d696e206c69737420697320616c726561647920616e2061646d696ea264697066735822122072ce0463649757ac84902cc940c137577b7165ef329f2fbbc0e7f26ec3aba32464736f6c634300060b0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/packages/ap-contracts/contracts/FDT/CMTA20FDT/SimpleRestrictedRuleEngine.sol b/packages/ap-contracts/contracts/FDT/CMTA20FDT/SimpleRestrictedRuleEngine.sol new file mode 100644 index 00000000..7c62c921 --- /dev/null +++ b/packages/ap-contracts/contracts/FDT/CMTA20FDT/SimpleRestrictedRuleEngine.sol @@ -0,0 +1,354 @@ +// "SPDX-License-Identifier: Apache-2.0" +pragma solidity ^0.6.10; + +import "@openzeppelin/contracts-ethereum-package/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol"; + + +/** + * @notice This contract allows a list of administrators to be tracked. This list can then be enforced + * on functions with administrative permissions. Only the owner of the contract should be allowed + * to modify the administrator list. + */ +contract Administratable is OwnableUpgradeSafe { + // The mapping to track administrator accounts - true is reserved for admin addresses. + mapping(address => bool) public administrators; + + // Events to allow tracking add/remove. + event AdminAdded(address indexed addedAdmin, address indexed addedBy); + event AdminRemoved(address indexed removedAdmin, address indexed removedBy); + + /** + * @notice Function modifier to enforce administrative permissions. + */ + modifier onlyAdministrator() { + require( + isAdministrator(msg.sender), + "Calling account is not an administrator." + ); + _; + } + + /** + * @notice Add an admin to the list. This should only be callable by the owner of the contract. + */ + function addAdmin(address adminToAdd) public onlyOwner { + // Verify the account is not already an admin + require( + administrators[adminToAdd] == false, + "Account to be added to admin list is already an admin" + ); + + // Set the address mapping to true to indicate it is an administrator account. + administrators[adminToAdd] = true; + + // Emit the event for any watchers. + emit AdminAdded(adminToAdd, msg.sender); + } + + /** + * @notice Remove an admin from the list. This should only be callable by the owner of the contract. + */ + function removeAdmin(address adminToRemove) public onlyOwner { + // Verify the account is an admin + require( + administrators[adminToRemove] == true, + "Account to be removed from admin list is not already an admin" + ); + + // Set the address mapping to false to indicate it is NOT an administrator account. + administrators[adminToRemove] = false; + + // Emit the event for any watchers. + emit AdminRemoved(adminToRemove, msg.sender); + } + + /** + * @notice Determine if the message sender is in the administrators list. + */ + function isAdministrator(address addressToTest) public view returns (bool) { + return administrators[addressToTest]; + } +} + +/** + * @notice Keeps track of whitelists and can check if sender and reciever are configured to allow a transfer. + * Only administrators can update the whitelists. + * Any address can only be a member of one whitelist at a time. + */ +contract Whitelistable is Administratable { + // Zero is reserved for indicating it is not on a whitelist + uint8 constant internal NO_WHITELIST = 0; + + // The mapping to keep track of which whitelist any address belongs to. + // 0 is reserved for no whitelist and is the default for all addresses. + mapping(address => uint8) public addressWhitelists; + + // The mapping to keep track of each whitelist's outbound whitelist flags. + // Boolean flag indicates whether outbound transfers are enabled. + mapping(uint8 => mapping(uint8 => bool)) public outboundWhitelistsEnabled; + + // Events to allow tracking add/remove. + event AddressAddedToWhitelist( + address indexed addedAddress, + uint8 indexed whitelist, + address indexed addedBy + ); + event AddressRemovedFromWhitelist( + address indexed removedAddress, + uint8 indexed whitelist, + address indexed removedBy + ); + event OutboundWhitelistUpdated( + address indexed updatedBy, + uint8 indexed sourceWhitelist, + uint8 indexed destinationWhitelist, + bool from, + bool to + ); + + /** + * @notice Sets an address's white list ID. Only administrators should be allowed to update this. + * If an address is on an existing whitelist, it will just get updated to the new value (removed from previous). + */ + function addToWhitelist(address addressToAdd, uint8 whitelist) + public + onlyAdministrator + { + // Verify the whitelist is valid + require(whitelist != NO_WHITELIST, "Invalid whitelist ID supplied"); + + // Save off the previous white list + uint8 previousWhitelist = addressWhitelists[addressToAdd]; + + // Set the address's white list ID + addressWhitelists[addressToAdd] = whitelist; + + // If the previous whitelist existed then we want to indicate it has been removed + if (previousWhitelist != NO_WHITELIST) { + // Emit the event for tracking + emit AddressRemovedFromWhitelist( + addressToAdd, + previousWhitelist, + msg.sender + ); + } + + // Emit the event for new whitelist + emit AddressAddedToWhitelist(addressToAdd, whitelist, msg.sender); + } + + /** + * @notice Clears out an address's white list ID. Only administrators should be allowed to update this. + */ + function removeFromWhitelist(address addressToRemove) + public + onlyAdministrator + { + // Save off the previous white list + uint8 previousWhitelist = addressWhitelists[addressToRemove]; + + // Zero out the previous white list + addressWhitelists[addressToRemove] = NO_WHITELIST; + + // Emit the event for tracking + emit AddressRemovedFromWhitelist( + addressToRemove, + previousWhitelist, + msg.sender + ); + } + + /** + * @notice Sets the flag to indicate whether source whitelist is allowed to send to destination whitelist. + * Only administrators should be allowed to update this. + */ + function updateOutboundWhitelistEnabled( + uint8 sourceWhitelist, + uint8 destinationWhitelist, + bool newEnabledValue + ) public onlyAdministrator { + // Get the old enabled flag + bool oldEnabledValue = outboundWhitelistsEnabled[sourceWhitelist][destinationWhitelist]; + + // Update to the new value + outboundWhitelistsEnabled[sourceWhitelist][destinationWhitelist] = newEnabledValue; + + // Emit event for tracking + emit OutboundWhitelistUpdated( + msg.sender, + sourceWhitelist, + destinationWhitelist, + oldEnabledValue, + newEnabledValue + ); + } + + /** + * @notice Determine if the a sender is allowed to send to the receiver. + * The source whitelist must be enabled to send to the whitelist where the receive exists. + */ + function checkWhitelistAllowed(address sender, address receiver) + public + view + returns (bool) + { + // First get each address white list + uint8 senderWhiteList = addressWhitelists[sender]; + uint8 receiverWhiteList = addressWhitelists[receiver]; + + // If either address is not on a white list then the check should fail + if ( + senderWhiteList == NO_WHITELIST || receiverWhiteList == NO_WHITELIST + ) { + return false; + } + + // Determine if the sending whitelist is allowed to send to the destination whitelist + return outboundWhitelistsEnabled[senderWhiteList][receiverWhiteList]; + } +} + +/** + * @notice Restrictions start off as enabled. Once they are disabled, they cannot be re-enabled. + * Only the owner may disable restrictions. + */ +contract Restrictable is OwnableUpgradeSafe { + // State variable to track whether restrictions are enabled. Defaults to true. + bool private _restrictionsEnabled = true; + + // Event emitted when flag is disabled + event RestrictionsDisabled(address indexed owner); + + /** + * @notice Function to update the enabled flag on restrictions to disabled. Only the owner should be able to call. + * This is a permanent change that cannot be undone + */ + function disableRestrictions() public onlyOwner { + require(_restrictionsEnabled, "Restrictions are already disabled."); + + // Set the flag + _restrictionsEnabled = false; + + // Trigger the event + emit RestrictionsDisabled(msg.sender); + } + + /** + * @notice View function to determine if restrictions are enabled + */ + function isRestrictionEnabled() public view returns (bool) { + return _restrictionsEnabled; + } +} + +/** + * @title IRule + * @dev IRule interface. + */ +interface IRule { + function isTransferValid(address _from, address _to, uint256 _amount) external view returns (bool isValid); + function detectTransferRestriction(address _from, address _to, uint256 _amount) external view returns (uint8); + function canReturnTransferRestrictionCode(uint8 _restrictionCode) external view returns (bool); + function messageForTransferRestriction(uint8 _restrictionCode) external view returns (string memory); +} + +/** + * @title IRuleEngine + * @dev IRuleEngine + */ +interface IRuleEngine { + function setRules(IRule[] calldata rules) external; + function ruleLength() external view returns (uint256); + function rule(uint256 ruleId) external view returns (IRule); + function rules() external view returns(IRule[] memory); + function validateTransfer(address _from, address _to, uint256 _amount) external view returns (bool); + function detectTransferRestriction(address _from, address _to, uint256 _value) external view returns (uint8); + function messageForTransferRestriction (uint8 _restrictionCode) external view returns (string memory); +} + +contract SimpleRestrictedRuleEngine is IRuleEngine, Whitelistable, Restrictable { + + // ERC1404 Error codes and messages + uint8 public constant SUCCESS_CODE = 0; + uint8 public constant FAILURE_NON_WHITELIST = 1; + string public constant SUCCESS_MESSAGE = "SUCCESS"; + string public constant FAILURE_NON_WHITELIST_MESSAGE = "The transfer was restricted due to white list configuration."; + string public constant UNKNOWN_ERROR = "Unknown Error Code"; + + + function setRules(IRule[] calldata rules) external override onlyOwner { + revert("Can not set any additional rules"); + } + + function ruleLength() external view override returns (uint256) { + return 0; + } + + function rule(uint256 ruleId) external view override returns (IRule) { + return IRule(address(0)); + } + + function rules() external view override returns(IRule[] memory) { + IRule[] memory rules; + return rules; + } + + /** + * @notice This function detects whether a transfer should be restricted and not allowed. + * If the function returns SUCCESS_CODE (0) then it should be allowed. + */ + function detectTransferRestriction(address from, address to, uint256) + public + view + override + returns (uint8) + { + // If the restrictions have been disabled by the owner, then just return success + // Logic defined in Restrictable parent class + if (!isRestrictionEnabled()) { + return SUCCESS_CODE; + } + + // If the contract owner is transferring, then ignore reistrictions + if (from == owner()) { + return SUCCESS_CODE; + } + + // Restrictions are enabled, so verify the whitelist config allows the transfer. + // Logic defined in Whitelistable parent class + if (!checkWhitelistAllowed(from, to)) { + return FAILURE_NON_WHITELIST; + } + + // If no restrictions were triggered return success + return SUCCESS_CODE; + } + + /** + * @notice This function allows a wallet or other client to get a human readable string to show + * a user if a transfer was restricted. It should return enough information for the user + * to know why it failed. + */ + function messageForTransferRestriction(uint8 restrictionCode) + public + view + override + returns (string memory) + { + if (restrictionCode == SUCCESS_CODE) { + return SUCCESS_MESSAGE; + } + + if (restrictionCode == FAILURE_NON_WHITELIST) { + return FAILURE_NON_WHITELIST_MESSAGE; + } + + // An unknown error code was passed in. + return UNKNOWN_ERROR; + } + + function validateTransfer(address from, address to, uint256 amount) public view override returns (bool) { + return detectTransferRestriction(from, to, amount) == SUCCESS_CODE; + } +} \ No newline at end of file