Address Contract Verified
Address
0x42Ac042C803e3aeFaCdF0dA576cB01e8bA3A16a0
Balance
0 ETH
Nonce
1
Code Size
9784 bytes
Creator
0x55749224...2409 at tx 0x7060a9e2...7ffdd2
Indexed Transactions
0
Contract Bytecode
9784 bytes
0x608060405234801561001057600080fd5b50600436106101775760003560e01c80637f82a5e7116100d8578063cd24be221161008c578063f38d249111610066578063f38d2491146105c8578063fabec44a146105db578063fedcc0521461065a57600080fd5b8063cd24be221461059a578063cf49020e146105a2578063f2fde38b146105b557600080fd5b80639585548a116100bd5780639585548a1461047c5780639e3e7bb91461048f578063afce4bea1461052657600080fd5b80637f82a5e7146104585780638da5cb5b1461046b57600080fd5b80636df237891161012f578063709bc7f311610114578063709bc7f3146103ab578063715018a61461043d57806371673bd01461044557600080fd5b80636df23789146103025780636ff6e83f1461031557600080fd5b80631ee9ce8b116101605780631ee9ce8b146101ac5780632c5d4f8e1461025757806361f898251461026d57600080fd5b80630f3ca8ca1461017c5780631320a65a14610191575b600080fd5b61018f61018a3660046120c4565b6106ef565b005b60035460ff1660405190151581526020015b60405180910390f35b6040805160608101825260015460ff808216835261010082048082166020808601919091526201000084049283169486019490945284516001600160f81b031960f894851b81168287015291841b821660218201529190921b9091166022820152825180820360030181526023909101835280519082012060009081526002918290529190912001546001600160a01b03165b6040516001600160a01b0390911681526020016101a3565b60035461010090046001600160a01b031661023f565b6040805160608101825260015460ff808216835261010082048082166020808601919091526201000084049283169486019490945284516001600160f81b031960f894851b81168287015291841b821660218201529190921b909116602282015282518082036003018152602390910183528051908201206000908152600290915220600501546001600160a01b031661023f565b61018f6103103660046120fc565b610a2d565b604080516060810182526001805460ff808216845261010082048082166020808701919091526201000084049283169587019590955285516001600160f81b031960f894851b81168288015291841b821660218201529190921b909116602282015283518082036003018152602390910184528051908301206000908152600290925291902001546001600160a01b031661023f565b6040805160608101825260015460ff808216835261010082048082166020808601919091526201000084049283169486019490945284516001600160f81b031960f894851b81168287015291841b821660218201529190921b909116602282015282518082036003018152602390910183528051908201206000908152600290915220546001600160a01b031661023f565b61018f610b6e565b61018f610453366004612119565b610b82565b61018f61046636600461215a565b610b99565b6000546001600160a01b031661023f565b61018f61048a366004612119565b611880565b6040805160608101825260015460ff808216835261010082048082166020808601919091526201000084049283169486019490945284516001600160f81b031960f894851b81168287015291841b821660218201529190921b9091166022820152825180820360039081018252602390920184528051908301206000908152600290925291902001546001600160a01b031661023f565b6105396105343660046120c4565b611b28565b6040516101a39190600060c0820190506001600160a01b038084511683528060208501511660208401528060408501511660408401528060608501511660608401528060808501511660808401528060a08501511660a08401525092915050565b61023f611be0565b61018f6105b03660046120fc565b611c5e565b61018f6105c33660046120fc565b611d9f565b61018f6105d63660046120c4565b611e2f565b61062e6040805160608101825260008082526020820181905291810191909152506040805160608101825260015460ff808216835261010082048116602084015262010000909104169181019190915290565b60408051825160ff908116825260208085015182169083015292820151909216908201526060016101a3565b6040805160608101825260015460ff808216835261010082048082166020808601919091526201000084049283169486019490945284516001600160f81b031960f894851b81168287015291841b821660218201529190921b909116602282015282518082036003018152602390910183528051908201206000908152600290915220600401546001600160a01b031661023f565b60035460ff161561076d5760405162461bcd60e51b815260206004820152602160248201527f63616e6e6f742063616c6c206f6e207265666572656e636520636f6e7472616360448201527f740000000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b60006002816107d4610784368690038601866121d9565b805160208083015160409384015184516001600160f81b031960f895861b81168286015292851b83166021820152931b166022830152825180830360030181526023909201909252805191012090565b81526020810191909152604001600020546001600160a01b03161461083b5760405162461bcd60e51b815260206004820152601760248201527f76657273696f6e206665746368656420616c72656164790000000000000000006044820152606401610764565b610843611be0565b6001600160a01b031663afce4bea826040518263ffffffff1660e01b815260040161086e919061222d565b60c060405180830381865afa15801561088b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108af9190612275565b600260006108c5610784368690038601866121d9565b815260208082019290925260409081016000908120845181546001600160a01b03199081166001600160a01b039283161783559486015160018301805487169183169190911790559285015160028083018054871692861692909217909155606086015160038301805487169186169190911790556080860151600483018054871691861691909117905560a0909501516005909101805490941692169190911790915561097b610784368590038501856121d9565b81526020019081526020016000206040516109e4919081546001600160a01b03908116825260018301548116602083015260028301548116604083015260038301548116606083015260048301548116608083015260059092015490911660a082015260c00190565b6040518091039020816040516109fa919061232e565b604051908190038120907f5846080f2085e3dfad8cb250efdba145f8982d2e81ba7f74478da7fab659322b90600090a350565b610a35612002565b60035460ff168015610ab95750306001600160a01b0316816001600160a01b0316632d5f11876040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aae9190612375565b6001600160a01b0316145b610b055760405162461bcd60e51b815260206004820181905260248201527f6f6e6c79207265666572656e636520636f6e74726163742063616e2063616c6c6044820152606401610764565b600380547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101006001600160a01b038416908102919091179091556040517ff068c7797c3b666af662a0e2f018804080dc37610a1b82b55006872b06d30ef590600090a250565b610b76612002565b610b80600061205c565b565b610b8c8282611880565b610b9582611e2f565b5050565b6001600160a01b038216610bef5760405162461bcd60e51b815260206004820152601f60248201527f696e76616c696420617267756d656e74202d207a65726f2061646472657373006044820152606401610764565b6001600160a01b038116158015610c09575060035460ff16155b15610c7c5760405162461bcd60e51b815260206004820152602a60248201527f6f6e6c79207265666572656e636520636f6e74726163742063616e206465706c60448201527f6f79206e657720494173000000000000000000000000000000000000000000006064820152608401610764565b6000826001600160a01b031663134e18f46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce09190612375565b90506000836001600160a01b0316636290865d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d469190612375565b90506000826001600160a01b031663f11abfd86040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dac9190612375565b90506000836001600160a01b0316633b3e12f46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e129190612375565b90506000846001600160a01b031663b4f3fcb76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e789190612375565b9050336001600160a01b0316876001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ec2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee69190612375565b6001600160a01b0316141580610f6f5750336001600160a01b0316856001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f639190612375565b6001600160a01b031614155b80610fed5750336001600160a01b0316846001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fbd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe19190612375565b6001600160a01b031614155b8061106b5750336001600160a01b0316836001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561103b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105f9190612375565b6001600160a01b031614155b806110e95750336001600160a01b0316826001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110dd9190612375565b6001600160a01b031614155b806111675750336001600160a01b0316816001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611137573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115b9190612375565b6001600160a01b031614155b156111da5760405162461bcd60e51b815260206004820152602a60248201527f63616c6c6572204e4f54206f776e6572206f6620616c6c20636f6e747261637460448201527f7320696d706163746564000000000000000000000000000000000000000000006064820152608401610764565b6001600160a01b03861661127a57600480546040517f52f1431b0000000000000000000000000000000000000000000000000000000081526001600160a01b038a8116938201939093529116906352f1431b906024016020604051808303816000875af115801561124f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112739190612375565b955061159a565b6040805160608101825260015460ff808216835261010082048082166020808601919091526201000084049283169486019490945284516001600160f81b031960f894851b81168287015291841b821660218201529190921b90911660228201528251808203600301815260239091019092528151910120611357876001600160a01b031663fabec44a6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611333573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107849190612392565b146113ca5760405162461bcd60e51b815260206004820152603260248201527f76657273696f6e206f66206e65772049412068617320746f206265207468652060448201527f73616d652061732063757272656e7420494100000000000000000000000000006064820152608401610764565b856001600160a01b0316631320a65a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611408573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142c91906123da565b8015611451575061143b611be0565b6001600160a01b0316866001600160a01b031614155b1561149e5760405162461bcd60e51b815260206004820181905260248201527f6e6577204941206973204e4f54207265666572656e636520636f6e74726163746044820152606401610764565b600480546040517fde87aeeb0000000000000000000000000000000000000000000000000000000081526001600160a01b038981169382019390935291169063de87aeeb90602401602060405180830381865afa158015611503573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152791906123da565b15801561154d5750611537611be0565b6001600160a01b0316866001600160a01b031614155b1561159a5760405162461bcd60e51b815260206004820152600a60248201527f696e76616c6964204941000000000000000000000000000000000000000000006044820152606401610764565b6040516392dd9d6560e01b81526001600160a01b0387811660048301528816906392dd9d6590602401600060405180830381600087803b1580156115dd57600080fd5b505af11580156115f1573d6000803e3d6000fd5b50506040516392dd9d6560e01b81526001600160a01b038981166004830152881692506392dd9d659150602401600060405180830381600087803b15801561163857600080fd5b505af115801561164c573d6000803e3d6000fd5b50506040516392dd9d6560e01b81526001600160a01b038981166004830152871692506392dd9d659150602401600060405180830381600087803b15801561169357600080fd5b505af11580156116a7573d6000803e3d6000fd5b50506040516392dd9d6560e01b81526001600160a01b038981166004830152851692506392dd9d659150602401600060405180830381600087803b1580156116ee57600080fd5b505af1158015611702573d6000803e3d6000fd5b50506040516392dd9d6560e01b81526001600160a01b038981166004830152841692506392dd9d659150602401600060405180830381600087803b15801561174957600080fd5b505af115801561175d573d6000803e3d6000fd5b50505050306001600160a01b0316836001600160a01b0316632d5f11876040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117cd9190612375565b6001600160a01b031603611837576040516392dd9d6560e01b81526001600160a01b0387811660048301528416906392dd9d6590602401600060405180830381600087803b15801561181e57600080fd5b505af1158015611832573d6000803e3d6000fd5b505050505b856001600160a01b0316876001600160a01b03167ff79ab4f8584958d3168dac16d1d96119f728316536f50639339b4202837051c860405160405180910390a350505050505050565b611888612002565b60035460ff166119005760405162461bcd60e51b815260206004820152602860248201527f4f4e4c59207265666572656e636520636f6e74726163742063616e206164642060448201527f76657273696f6e730000000000000000000000000000000000000000000000006064820152608401610764565b6000600281611917610784368790038701876121d9565b81526020810191909152604001600020546001600160a01b03161461197e5760405162461bcd60e51b815260206004820152601660248201527f76657273696f6e20616c726561647920657869737473000000000000000000006044820152606401610764565b600061199060408301602084016120fc565b6001600160a01b0316141580156119c0575060006119b460608301604084016120fc565b6001600160a01b031614155b80156119e5575060006119d960808301606084016120fc565b6001600160a01b031614155b8015611a0a575060006119fe60c0830160a084016120fc565b6001600160a01b031614155b8015611a2f57506000611a2360a08301608084016120fc565b6001600160a01b031614155b8015611a5157506000611a4560208301836120fc565b6001600160a01b031614155b611a9d5760405162461bcd60e51b815260206004820152601f60248201527f696e76616c696420617267756d656e74202d207a65726f2061646472657373006044820152606401610764565b8060026000611ab4610784368790038701876121d9565b81526020019081526020016000208181611ace91906123fc565b5050604051611ade908290612501565b604051809103902082604051611af4919061232e565b604051908190038120907faecad55510e8cbc2b82b73c5c6d78c169403cb719460198f517d41cf7700b71b90600090a35050565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915260026000611b70610784368690038601866121d9565b81526020808201929092526040908101600020815160c08101835281546001600160a01b039081168252600183015481169482019490945260028201548416928101929092526003810154831660608301526004810154831660808301526005015490911660a082015292915050565b6000600360019054906101000a90046001600160a01b03166001600160a01b0316632d5f11876040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c599190612375565b905090565b611c66612002565b60035460ff168015611d095750600354604080517f2d5f11870000000000000000000000000000000000000000000000000000000081529051309261010090046001600160a01b031691632d5f11879160048083019260209291908290030181865afa158015611cda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cfe9190612375565b6001600160a01b0316145b611d555760405162461bcd60e51b815260206004820181905260248201527f6f6e6c79207265666572656e636520636f6e74726163742063616e2063616c6c6044820152606401610764565b600480546001600160a01b0319166001600160a01b0383169081179091556040517f5fb25b36f93b3d8443f7502abdc1157f581f15db724459ffb2800fce6132a00890600090a250565b611da7612002565b6001600160a01b038116611e235760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610764565b611e2c8161205c565b50565b611e37612002565b6040805160608101825260015460ff808216835261010082048082166020808601919091526201000084049283169486019490945284516001600160f81b031960f894851b81168287015291841b821660218201529190921b90911660228201528251808203600301815260239091019092528151910120611ec1610784368490038401846121d9565b03611f0e5760405162461bcd60e51b815260206004820152601660248201527f76657273696f6e20616c726561647920696e20757365000000000000000000006044820152606401610764565b6000600281611f25610784368690038601866121d9565b81526020810191909152604001600020546001600160a01b031603611fb25760405162461bcd60e51b815260206004820152602760248201527f696e76616c696420617267756d656e74202d206e6f6e206578697374696e672060448201527f76657273696f6e000000000000000000000000000000000000000000000000006064820152608401610764565b806001611fbf8282612595565b5050604051611fcf90829061232e565b604051908190038120907f0a46bc1766225d5a82bc50155575dc428902e93470e34ceaf7e0faae128fe0ab90600090a250565b6000546001600160a01b03163314610b805760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610764565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000606082840312156120be57600080fd5b50919050565b6000606082840312156120d657600080fd5b6120e083836120ac565b9392505050565b6001600160a01b0381168114611e2c57600080fd5b60006020828403121561210e57600080fd5b81356120e0816120e7565b60008082840361012081121561212e57600080fd5b61213885856120ac565b925060c0605f198201121561214c57600080fd5b506060830190509250929050565b6000806040838503121561216d57600080fd5b8235612178816120e7565b91506020830135612188816120e7565b809150509250929050565b6040516060810167ffffffffffffffff811182821017156121c457634e487b7160e01b600052604160045260246000fd5b60405290565b60ff81168114611e2c57600080fd5b6000606082840312156121eb57600080fd5b6121f3612193565b82356121fe816121ca565b8152602083013561220e816121ca565b60208201526040830135612221816121ca565b60408201529392505050565b60608101823561223c816121ca565b60ff168252602083013561224f816121ca565b60ff1660208301526040830135612265816121ca565b60ff811660408401525092915050565b600060c0828403121561228757600080fd5b60405160c0810181811067ffffffffffffffff821117156122b857634e487b7160e01b600052604160045260246000fd5b60405282516122c6816120e7565b815260208301516122d6816120e7565b602082015260408301516122e9816120e7565b604082015260608301516122fc816120e7565b6060820152608083015161230f816120e7565b608082015260a0830151612322816120e7565b60a08201529392505050565b6000823561233b816121ca565b60ff168252602083013561234e816121ca565b60ff1660208301526040830135612364816121ca565b60ff16604083015250606001919050565b60006020828403121561238757600080fd5b81516120e0816120e7565b6000606082840312156123a457600080fd5b6123ac612193565b82516123b7816121ca565b815260208301516123c7816121ca565b60208201526040830151612221816121ca565b6000602082840312156123ec57600080fd5b815180151581146120e057600080fd5b8135612407816120e7565b81546001600160a01b0319166001600160a01b03821617825550602082013561242f816120e7565b6001820180546001600160a01b0319166001600160a01b03831617905550604082013561245b816120e7565b6002820180546001600160a01b0319166001600160a01b038316179055506060820135612487816120e7565b6003820180546001600160a01b0319166001600160a01b0383161790555060808201356124b3816120e7565b6004820180546001600160a01b0319166001600160a01b0383161790555060a08201356124df816120e7565b6005820180546001600160a01b0319166001600160a01b038316179055505050565b6000823561250e816120e7565b6001600160a01b03908116835260208401359061252a826120e7565b9081166020840152604084013590612541826120e7565b9081166040840152606084013590612558826120e7565b908116606084015260808401359061256f826120e7565b908116608084015260a084013590612586826120e7565b1660a08301525060c001919050565b81356125a0816121ca565b60ff8116905081548160ff19821617835560208401356125bf816121ca565b61ff008160081b169050808361ffff1984161717845560408501356125e3816121ca565b62ff00008160101b168462ffffff19851617831717855550505050505056fea26469706673582212204d63d6045361f8a4fb02d4b658890107fa7a578c7af238ae574453329264279764736f6c63430008110033
Verified Source Code Full Match
Compiler: v0.8.17+commit.8df45f5f
EVM: london
Optimization: Yes (1000 runs)
TREXImplementationAuthority.sol 333 lines
// SPDX-License-Identifier: GPL-3.0
//
// :+#####%%%%%%%%%%%%%%+
// .-*@@@%+.:+%@@@@@%%#***%@@%=
// :=*%@@@#=. :#@@% *@@@%=
// .-+*%@%*-.:+%@@@@@@+. -*+: .=#. :%@@@%-
// :=*@@@@%%@@@@@@@@@%@@@- .=#@@@%@%= =@@@@#.
// -=+#%@@%#*=:. :%@@@@%. -*@@#*@@@@@@@#=:- *@@@@+
// =@@%=:. :=: *@@@@@%#- =%*%@@@@#+-. =+ :%@@@%-
// -@@%. .+@@@ =+=-. @@#- +@@@%- =@@@@%:
// :@@@. .+@@#%: : .=*=-::.-%@@@+*@@= +@@@@#.
// %@@: +@%%* =%@@@@@@@@@@@#. .*@%- +@@@@*.
// #@@= .+@@@@%:=*@@@@@- :%@%: .*@@@@+
// *@@* +@@@#-@@%-:%@@* +@@#. :%@@@@-
// -@@% .:-=++*##%%%@@@@@@@@@@@@*. :@+.@@@%: .#@@+ =@@@@#:
// .@@@*-+*#%%%@@@@@@@@@@@@@@@@%%#**@@%@@@. *@=*@@# :#@%= .#@@@@#-
// -%@@@@@@@@@@@@@@@*+==-:-@@@= *@# .#@*-=*@@@@%= -%@@@* =@@@@@%-
// -+%@@@#. %@%%= -@@:+@: -@@* *@@*-:: -%@@%=. .*@@@@@#
// *@@@* +@* *@@##@@- #@*@@+ -@@= . :+@@@#: .-+@@@%+-
// +@@@%*@@:..=@@@@* .@@@* .#@#. .=+- .=%@@@*. :+#@@@@*=:
// =@@@@%@@@@@@@@@@@@@@@@@@@@@@%- :+#*. :*@@@%=. .=#@@@@%+:
// .%@@= ..... .=#@@+. .#@@@*: -*%@@@@%+.
// +@@#+===---:::... .=%@@*- +@@@+. -*@@@@@%+.
// -@@@@@@@@@@@@@@@@@@@@@@%@@@@= -@@@+ -#@@@@@#=.
// ..:::---===+++***###%%%@@@#- .#@@+ -*@@@@@#=.
// @@@@@@+. +@@*. .+@@@@@%=.
// -@@@@@= =@@%: -#@@@@%+.
// +@@@@@. =@@@= .+@@@@@*:
// #@@@@#:%@@#. :*@@@@#-
// @@@@@%@@@= :#@@@@+.
// :@@@@@@@#.:#@@@%-
// +@@@@@@-.*@@@*:
// #@@@@#.=@@@+.
// @@@@+-%@%=
// :@@@#%@%=
// +@@@@%-
// :#%%=
//
/**
* NOTICE
*
* The T-REX software is licensed under a proprietary license or the GPL v.3.
* If you choose to receive it under the GPL v.3 license, the following applies:
* T-REX is a suite of smart contracts implementing the ERC-3643 standard and
* developed by Tokeny to manage and transfer financial assets on EVM blockchains
*
* Copyright (C) 2023, Tokeny sàrl.
*
* 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 <https://www.gnu.org/licenses/>.
*/
pragma solidity 0.8.17;
import "@openzeppelin/contracts/access/Ownable.sol";
import "./ITREXImplementationAuthority.sol";
import "../../token/IToken.sol";
import "../interface/IProxy.sol";
import "../../factory/ITREXFactory.sol";
import "./IIAFactory.sol";
contract TREXImplementationAuthority is ITREXImplementationAuthority, Ownable {
/// variables
/// current version
Version private _currentVersion;
/// mapping to get contracts of each version
mapping(bytes32 => TREXContracts) private _contracts;
/// reference ImplementationAuthority used by the TREXFactory
bool private _reference;
/// address of TREXFactory contract
address private _trexFactory;
/// address of factory for TREXImplementationAuthority contracts
address private _iaFactory;
/// functions
/**
* @dev Constructor of the ImplementationAuthority contract
* @param referenceStatus boolean value determining if the contract
* is the main IA or an auxiliary contract
* @param trexFactory the address of TREXFactory referencing the main IA
* if `referenceStatus` is true then `trexFactory` at deployment is set
* on zero address. In that scenario, call `setTREXFactory` post-deployment
* @param iaFactory the address for the factory of IA contracts
* emits `ImplementationAuthoritySet` event
* emits a `IAFactorySet` event
*/
constructor (bool referenceStatus, address trexFactory, address iaFactory) {
_reference = referenceStatus;
_trexFactory = trexFactory;
_iaFactory = iaFactory;
emit ImplementationAuthoritySet(referenceStatus, trexFactory);
emit IAFactorySet(iaFactory);
}
/**
* @dev See {ITREXImplementationAuthority-setTREXFactory}.
*/
function setTREXFactory(address trexFactory) external override onlyOwner {
require(
isReferenceContract() &&
ITREXFactory(trexFactory).getImplementationAuthority() == address(this)
, "only reference contract can call");
_trexFactory = trexFactory;
emit TREXFactorySet(trexFactory);
}
/**
* @dev See {ITREXImplementationAuthority-setIAFactory}.
*/
function setIAFactory(address iaFactory) external override onlyOwner {
require(
isReferenceContract() &&
ITREXFactory(_trexFactory).getImplementationAuthority() == address(this)
, "only reference contract can call");
_iaFactory = iaFactory;
emit IAFactorySet(iaFactory);
}
/**
* @dev See {ITREXImplementationAuthority-useTREXVersion}.
*/
function addAndUseTREXVersion(Version calldata _version, TREXContracts calldata _trex) external override {
addTREXVersion(_version, _trex);
useTREXVersion(_version);
}
/**
* @dev See {ITREXImplementationAuthority-fetchVersionList}.
*/
function fetchVersion(Version calldata _version) external override {
require(!isReferenceContract(), "cannot call on reference contract");
if (_contracts[_versionToBytes(_version)].tokenImplementation != address(0)) {
revert("version fetched already");
}
_contracts[_versionToBytes(_version)] =
ITREXImplementationAuthority(getReferenceContract()).getContracts(_version);
emit TREXVersionFetched(_version, _contracts[_versionToBytes(_version)]);
}
/**
* @dev See {ITREXImplementationAuthority-changeImplementationAuthority}.
*/
// solhint-disable-next-line code-complexity, function-max-lines
function changeImplementationAuthority(address _token, address _newImplementationAuthority) external override {
require(_token != address(0), "invalid argument - zero address");
if(_newImplementationAuthority == address(0) && !isReferenceContract()){
revert("only reference contract can deploy new IAs");}
address _ir = address(IToken(_token).identityRegistry());
address _mc = address(IToken(_token).compliance());
address _irs = address(IIdentityRegistry(_ir).identityStorage());
address _ctr = address(IIdentityRegistry(_ir).topicsRegistry());
address _tir = address(IIdentityRegistry(_ir).issuersRegistry());
// calling this function requires ownership of ALL contracts of the T-REX suite
if(
Ownable(_token).owner() != msg.sender
|| Ownable(_ir).owner() != msg.sender
|| Ownable(_mc).owner() != msg.sender
|| Ownable(_irs).owner() != msg.sender
|| Ownable(_ctr).owner() != msg.sender
|| Ownable(_tir).owner() != msg.sender) {
revert("caller NOT owner of all contracts impacted");
}
if(_newImplementationAuthority == address(0)) {
_newImplementationAuthority = IIAFactory(_iaFactory).deployIA(_token);
}
else {
if(
_versionToBytes(ITREXImplementationAuthority(_newImplementationAuthority).getCurrentVersion()) !=
_versionToBytes(_currentVersion)) {
revert("version of new IA has to be the same as current IA");
}
if(
ITREXImplementationAuthority(_newImplementationAuthority).isReferenceContract() &&
_newImplementationAuthority != getReferenceContract()) {
revert("new IA is NOT reference contract");
}
if(
!IIAFactory(_iaFactory).deployedByFactory(_newImplementationAuthority) &&
_newImplementationAuthority != getReferenceContract()) {
revert("invalid IA");
}
}
IProxy(_token).setImplementationAuthority(_newImplementationAuthority);
IProxy(_ir).setImplementationAuthority(_newImplementationAuthority);
IProxy(_mc).setImplementationAuthority(_newImplementationAuthority);
IProxy(_ctr).setImplementationAuthority(_newImplementationAuthority);
IProxy(_tir).setImplementationAuthority(_newImplementationAuthority);
// IRS can be shared by multiple tokens, and therefore could have been updated already
if (IProxy(_irs).getImplementationAuthority() == address(this)) {
IProxy(_irs).setImplementationAuthority(_newImplementationAuthority);
}
emit ImplementationAuthorityChanged(_token, _newImplementationAuthority);
}
/**
* @dev See {ITREXImplementationAuthority-getCurrentVersion}.
*/
function getCurrentVersion() external view override returns (Version memory) {
return _currentVersion;
}
/**
* @dev See {ITREXImplementationAuthority-getContracts}.
*/
function getContracts(Version calldata _version) external view override returns (TREXContracts memory) {
return _contracts[_versionToBytes(_version)];
}
/**
* @dev See {ITREXImplementationAuthority-getTREXFactory}.
*/
function getTREXFactory() external view override returns (address) {
return _trexFactory;
}
/**
* @dev See {ITREXImplementationAuthority-getTokenImplementation}.
*/
function getTokenImplementation() external view override returns (address) {
return _contracts[_versionToBytes(_currentVersion)].tokenImplementation;
}
/**
* @dev See {ITREXImplementationAuthority-getCTRImplementation}.
*/
function getCTRImplementation() external view override returns (address) {
return _contracts[_versionToBytes(_currentVersion)].ctrImplementation;
}
/**
* @dev See {ITREXImplementationAuthority-getIRImplementation}.
*/
function getIRImplementation() external view override returns (address) {
return _contracts[_versionToBytes(_currentVersion)].irImplementation;
}
/**
* @dev See {ITREXImplementationAuthority-getIRSImplementation}.
*/
function getIRSImplementation() external view override returns (address) {
return _contracts[_versionToBytes(_currentVersion)].irsImplementation;
}
/**
* @dev See {ITREXImplementationAuthority-getTIRImplementation}.
*/
function getTIRImplementation() external view override returns (address) {
return _contracts[_versionToBytes(_currentVersion)].tirImplementation;
}
/**
* @dev See {ITREXImplementationAuthority-getMCImplementation}.
*/
function getMCImplementation() external view override returns (address) {
return _contracts[_versionToBytes(_currentVersion)].mcImplementation;
}
/**
* @dev See {ITREXImplementationAuthority-addTREXVersion}.
*/
function addTREXVersion(Version calldata _version, TREXContracts calldata _trex) public override onlyOwner {
require(isReferenceContract(), "ONLY reference contract can add versions");
if (_contracts[_versionToBytes(_version)].tokenImplementation != address(0)) {
revert("version already exists");
}
require(
_trex.ctrImplementation != address(0)
&& _trex.irImplementation != address(0)
&& _trex.irsImplementation != address(0)
&& _trex.mcImplementation != address(0)
&& _trex.tirImplementation != address(0)
&& _trex.tokenImplementation != address(0)
, "invalid argument - zero address");
_contracts[_versionToBytes(_version)] = _trex;
emit TREXVersionAdded(_version, _trex);
}
/**
* @dev See {ITREXImplementationAuthority-useTREXVersion}.
*/
function useTREXVersion(Version calldata _version) public override onlyOwner {
if (_versionToBytes(_version) == _versionToBytes(_currentVersion)) {
revert("version already in use");
}
if (_contracts[_versionToBytes(_version)].tokenImplementation == address(0)) {
revert("invalid argument - non existing version");
}
_currentVersion = _version;
emit VersionUpdated(_version);
}
/**
* @dev See {ITREXImplementationAuthority-isReferenceContract}.
*/
function isReferenceContract() public view override returns (bool) {
return _reference;
}
/**
* @dev See {ITREXImplementationAuthority-getReferenceContract}.
*/
function getReferenceContract() public view override returns (address) {
return ITREXFactory(_trexFactory).getImplementationAuthority();
}
/**
* @dev casting function Version => bytes to allow compare values easier
*/
function _versionToBytes(Version memory _version) private pure returns(bytes32) {
return bytes32(keccak256(abi.encodePacked(_version.major, _version.minor, _version.patch)));
}
}
Ownable.sol 83 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
ITREXImplementationAuthority.sol 262 lines
// SPDX-License-Identifier: GPL-3.0
//
// :+#####%%%%%%%%%%%%%%+
// .-*@@@%+.:+%@@@@@%%#***%@@%=
// :=*%@@@#=. :#@@% *@@@%=
// .-+*%@%*-.:+%@@@@@@+. -*+: .=#. :%@@@%-
// :=*@@@@%%@@@@@@@@@%@@@- .=#@@@%@%= =@@@@#.
// -=+#%@@%#*=:. :%@@@@%. -*@@#*@@@@@@@#=:- *@@@@+
// =@@%=:. :=: *@@@@@%#- =%*%@@@@#+-. =+ :%@@@%-
// -@@%. .+@@@ =+=-. @@#- +@@@%- =@@@@%:
// :@@@. .+@@#%: : .=*=-::.-%@@@+*@@= +@@@@#.
// %@@: +@%%* =%@@@@@@@@@@@#. .*@%- +@@@@*.
// #@@= .+@@@@%:=*@@@@@- :%@%: .*@@@@+
// *@@* +@@@#-@@%-:%@@* +@@#. :%@@@@-
// -@@% .:-=++*##%%%@@@@@@@@@@@@*. :@+.@@@%: .#@@+ =@@@@#:
// .@@@*-+*#%%%@@@@@@@@@@@@@@@@%%#**@@%@@@. *@=*@@# :#@%= .#@@@@#-
// -%@@@@@@@@@@@@@@@*+==-:-@@@= *@# .#@*-=*@@@@%= -%@@@* =@@@@@%-
// -+%@@@#. %@%%= -@@:+@: -@@* *@@*-:: -%@@%=. .*@@@@@#
// *@@@* +@* *@@##@@- #@*@@+ -@@= . :+@@@#: .-+@@@%+-
// +@@@%*@@:..=@@@@* .@@@* .#@#. .=+- .=%@@@*. :+#@@@@*=:
// =@@@@%@@@@@@@@@@@@@@@@@@@@@@%- :+#*. :*@@@%=. .=#@@@@%+:
// .%@@= ..... .=#@@+. .#@@@*: -*%@@@@%+.
// +@@#+===---:::... .=%@@*- +@@@+. -*@@@@@%+.
// -@@@@@@@@@@@@@@@@@@@@@@%@@@@= -@@@+ -#@@@@@#=.
// ..:::---===+++***###%%%@@@#- .#@@+ -*@@@@@#=.
// @@@@@@+. +@@*. .+@@@@@%=.
// -@@@@@= =@@%: -#@@@@%+.
// +@@@@@. =@@@= .+@@@@@*:
// #@@@@#:%@@#. :*@@@@#-
// @@@@@%@@@= :#@@@@+.
// :@@@@@@@#.:#@@@%-
// +@@@@@@-.*@@@*:
// #@@@@#.=@@@+.
// @@@@+-%@%=
// :@@@#%@%=
// +@@@@%-
// :#%%=
//
/**
* NOTICE
*
* The T-REX software is licensed under a proprietary license or the GPL v.3.
* If you choose to receive it under the GPL v.3 license, the following applies:
* T-REX is a suite of smart contracts implementing the ERC-3643 standard and
* developed by Tokeny to manage and transfer financial assets on EVM blockchains
*
* Copyright (C) 2023, Tokeny sàrl.
*
* 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 <https://www.gnu.org/licenses/>.
*/
pragma solidity 0.8.17;
interface ITREXImplementationAuthority {
/// types
struct TREXContracts {
// address of token implementation contract
address tokenImplementation;
// address of ClaimTopicsRegistry implementation contract
address ctrImplementation;
// address of IdentityRegistry implementation contract
address irImplementation;
// address of IdentityRegistryStorage implementation contract
address irsImplementation;
// address of TrustedIssuersRegistry implementation contract
address tirImplementation;
// address of ModularCompliance implementation contract
address mcImplementation;
}
struct Version {
// major version
uint8 major;
// minor version
uint8 minor;
// patch version
uint8 patch;
}
/// events
/// event emitted when a new TREX version is added to the contract memory
event TREXVersionAdded(Version indexed version, TREXContracts indexed trex);
/// event emitted when a new TREX version is fetched from reference contract by auxiliary contract
event TREXVersionFetched(Version indexed version, TREXContracts indexed trex);
/// event emitted when the current version is updated
event VersionUpdated(Version indexed version);
/// event emitted by the constructor when the IA is deployed
event ImplementationAuthoritySet(bool referenceStatus, address trexFactory);
/// event emitted when the TREX factory address is set
event TREXFactorySet(address indexed trexFactory);
/// event emitted when the IA factory address is set
event IAFactorySet(address indexed iaFactory);
/// event emitted when a token issuer decides to change current IA for a new one
event ImplementationAuthorityChanged(address indexed _token, address indexed _newImplementationAuthority);
/// functions
/**
* @dev allows to fetch a TREX version available on the reference contract
* can be called only from auxiliary contracts, not on reference (main) contract
* throws if the version was already fetched
* adds the new version on the local storage
* allowing the update of contracts through the `useTREXVersion` afterwards
*/
function fetchVersion(Version calldata _version) external;
/**
* @dev setter for _trexFactory variable
* _trexFactory is set at deployment for auxiliary contracts
* for main contract it must be set post-deployment as main IA is
* deployed before the TREXFactory.
* @param trexFactory the address of TREXFactory contract
* emits a TREXFactorySet event
* only Owner can call
* can be called only on main contract, auxiliary contracts cannot call
*/
function setTREXFactory(address trexFactory) external;
/**
* @dev setter for _iaFactory variable
* _iaFactory is set at zero address for auxiliary contracts
* for main contract it can be set post-deployment or at deployment
* in the constructor
* @param iaFactory the address of IAFactory contract
* emits a IAFactorySet event
* only Owner can call
* can be called only on main contract, auxiliary contracts cannot call
*/
function setIAFactory(address iaFactory) external;
/**
* @dev adds a new Version of TREXContracts to the mapping
* only callable on the reference contract
* only Owner can call this function
* @param _version the new version to add to the mapping
* @param _trex the list of contracts corresponding to the new version
* _trex cannot contain zero addresses
* emits a `TREXVersionAdded` event
*/
function addTREXVersion(Version calldata _version, TREXContracts calldata _trex) external;
/**
* @dev updates the current version in use by the proxies
* variation of the `useTREXVersion` allowing to use a new version
* this function calls in a single transaction the `addTREXVersion`
* and the `useTREXVersion` using an existing version
* @param _version the version to use
* @param _trex the set of contracts corresponding to the version
* only Owner can call (check performed in addTREXVersion)
* only reference contract can call (check performed in addTREXVersion)
* emits a `TREXVersionAdded`event
* emits a `VersionUpdated` event
*/
function addAndUseTREXVersion(Version calldata _version, TREXContracts calldata _trex) external;
/**
* @dev updates the current version in use by the proxies
* @param _version the version to use
* reverts if _version is already used or if version does not exist
* only Owner can call
* emits a `VersionUpdated` event
*/
function useTREXVersion(Version calldata _version) external;
/**
* @dev change the implementationAuthority address of all proxy contracts linked to a given token
* only the owner of all proxy contracts can call this function
* @param _token the address of the token proxy
* @param _newImplementationAuthority the address of the new IA contract
* caller has to be owner of all contracts linked to the token and impacted by the change
* Set _newImplementationAuthority on zero address to deploy a new IA contract
* New IA contracts can only be deployed ONCE per token and only if current IA is the main IA
* if _newImplementationAuthority is not a new contract it must be using the same version
* as the current IA contract.
* calls `setImplementationAuthority` on all proxies linked to the token
* emits a `ImplementationAuthorityChanged` event
*/
function changeImplementationAuthority(address _token, address _newImplementationAuthority) external;
/**
* @dev getter function returning the current version of contracts used by proxies
*/
function getCurrentVersion() external view returns (Version memory);
/**
* @dev getter function returning the contracts corresponding to a version
* @param _version the version that contracts are requested for
*/
function getContracts(Version calldata _version) external view returns (TREXContracts memory);
/**
* @dev getter function returning address of reference TREX factory
*/
function getTREXFactory() external view returns (address);
/**
* @dev getter function returning address of token contract implementation
* currently used by the proxies using this TREXImplementationAuthority
*/
function getTokenImplementation() external view returns (address);
/**
* @dev getter function returning address of ClaimTopicsRegistry contract implementation
* currently used by the proxies using this TREXImplementationAuthority
*/
function getCTRImplementation() external view returns (address);
/**
* @dev getter function returning address of IdentityRegistry contract implementation
* currently used by the proxies using this TREXImplementationAuthority
*/
function getIRImplementation() external view returns (address);
/**
* @dev getter function returning address of IdentityRegistryStorage contract implementation
* currently used by the proxies using this TREXImplementationAuthority
*/
function getIRSImplementation() external view returns (address);
/**
* @dev getter function returning address of TrustedIssuersRegistry contract implementation
* currently used by the proxies using this TREXImplementationAuthority
*/
function getTIRImplementation() external view returns (address);
/**
* @dev getter function returning address of ModularCompliance contract implementation
* currently used by the proxies using this TREXImplementationAuthority
*/
function getMCImplementation() external view returns (address);
/**
* @dev returns true if the contract is the main contract
* returns false if the contract is an auxiliary contract
*/
function isReferenceContract() external view returns (bool);
/**
* @dev getter for reference contract address
*/
function getReferenceContract() external view returns (address);
}
IToken.sol 460 lines
// SPDX-License-Identifier: GPL-3.0
//
// :+#####%%%%%%%%%%%%%%+
// .-*@@@%+.:+%@@@@@%%#***%@@%=
// :=*%@@@#=. :#@@% *@@@%=
// .-+*%@%*-.:+%@@@@@@+. -*+: .=#. :%@@@%-
// :=*@@@@%%@@@@@@@@@%@@@- .=#@@@%@%= =@@@@#.
// -=+#%@@%#*=:. :%@@@@%. -*@@#*@@@@@@@#=:- *@@@@+
// =@@%=:. :=: *@@@@@%#- =%*%@@@@#+-. =+ :%@@@%-
// -@@%. .+@@@ =+=-. @@#- +@@@%- =@@@@%:
// :@@@. .+@@#%: : .=*=-::.-%@@@+*@@= +@@@@#.
// %@@: +@%%* =%@@@@@@@@@@@#. .*@%- +@@@@*.
// #@@= .+@@@@%:=*@@@@@- :%@%: .*@@@@+
// *@@* +@@@#-@@%-:%@@* +@@#. :%@@@@-
// -@@% .:-=++*##%%%@@@@@@@@@@@@*. :@+.@@@%: .#@@+ =@@@@#:
// .@@@*-+*#%%%@@@@@@@@@@@@@@@@%%#**@@%@@@. *@=*@@# :#@%= .#@@@@#-
// -%@@@@@@@@@@@@@@@*+==-:-@@@= *@# .#@*-=*@@@@%= -%@@@* =@@@@@%-
// -+%@@@#. %@%%= -@@:+@: -@@* *@@*-:: -%@@%=. .*@@@@@#
// *@@@* +@* *@@##@@- #@*@@+ -@@= . :+@@@#: .-+@@@%+-
// +@@@%*@@:..=@@@@* .@@@* .#@#. .=+- .=%@@@*. :+#@@@@*=:
// =@@@@%@@@@@@@@@@@@@@@@@@@@@@%- :+#*. :*@@@%=. .=#@@@@%+:
// .%@@= ..... .=#@@+. .#@@@*: -*%@@@@%+.
// +@@#+===---:::... .=%@@*- +@@@+. -*@@@@@%+.
// -@@@@@@@@@@@@@@@@@@@@@@%@@@@= -@@@+ -#@@@@@#=.
// ..:::---===+++***###%%%@@@#- .#@@+ -*@@@@@#=.
// @@@@@@+. +@@*. .+@@@@@%=.
// -@@@@@= =@@%: -#@@@@%+.
// +@@@@@. =@@@= .+@@@@@*:
// #@@@@#:%@@#. :*@@@@#-
// @@@@@%@@@= :#@@@@+.
// :@@@@@@@#.:#@@@%-
// +@@@@@@-.*@@@*:
// #@@@@#.=@@@+.
// @@@@+-%@%=
// :@@@#%@%=
// +@@@@%-
// :#%%=
//
/**
* NOTICE
*
* The T-REX software is licensed under a proprietary license or the GPL v.3.
* If you choose to receive it under the GPL v.3 license, the following applies:
* T-REX is a suite of smart contracts implementing the ERC-3643 standard and
* developed by Tokeny to manage and transfer financial assets on EVM blockchains
*
* Copyright (C) 2023, Tokeny sàrl.
*
* 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 <https://www.gnu.org/licenses/>.
*/
pragma solidity 0.8.17;
import "../registry/interface/IIdentityRegistry.sol";
import "../compliance/modular/IModularCompliance.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
/// @dev interface
interface IToken is IERC20 {
/// events
/**
* this event is emitted when the token information is updated.
* the event is emitted by the token init function and by the setTokenInformation function
* `_newName` is the name of the token
* `_newSymbol` is the symbol of the token
* `_newDecimals` is the decimals of the token
* `_newVersion` is the version of the token, current version is 3.0
* `_newOnchainID` is the address of the onchainID of the token
*/
event UpdatedTokenInformation(string indexed _newName, string indexed _newSymbol, uint8 _newDecimals, string
_newVersion, address indexed _newOnchainID);
/**
* this event is emitted when the IdentityRegistry has been set for the token
* the event is emitted by the token constructor and by the setIdentityRegistry function
* `_identityRegistry` is the address of the Identity Registry of the token
*/
event IdentityRegistryAdded(address indexed _identityRegistry);
/**
* this event is emitted when the Compliance has been set for the token
* the event is emitted by the token constructor and by the setCompliance function
* `_compliance` is the address of the Compliance contract of the token
*/
event ComplianceAdded(address indexed _compliance);
/**
* this event is emitted when an investor successfully recovers his tokens
* the event is emitted by the recoveryAddress function
* `_lostWallet` is the address of the wallet that the investor lost access to
* `_newWallet` is the address of the wallet that the investor provided for the recovery
* `_investorOnchainID` is the address of the onchainID of the investor who asked for a recovery
*/
event RecoverySuccess(address indexed _lostWallet, address indexed _newWallet, address indexed _investorOnchainID);
/**
* this event is emitted when the wallet of an investor is frozen or unfrozen
* the event is emitted by setAddressFrozen and batchSetAddressFrozen functions
* `_userAddress` is the wallet of the investor that is concerned by the freezing status
* `_isFrozen` is the freezing status of the wallet
* if `_isFrozen` equals `true` the wallet is frozen after emission of the event
* if `_isFrozen` equals `false` the wallet is unfrozen after emission of the event
* `_owner` is the address of the agent who called the function to freeze the wallet
*/
event AddressFrozen(address indexed _userAddress, bool indexed _isFrozen, address indexed _owner);
/**
* this event is emitted when a certain amount of tokens is frozen on a wallet
* the event is emitted by freezePartialTokens and batchFreezePartialTokens functions
* `_userAddress` is the wallet of the investor that is concerned by the freezing status
* `_amount` is the amount of tokens that are frozen
*/
event TokensFrozen(address indexed _userAddress, uint256 _amount);
/**
* this event is emitted when a certain amount of tokens is unfrozen on a wallet
* the event is emitted by unfreezePartialTokens and batchUnfreezePartialTokens functions
* `_userAddress` is the wallet of the investor that is concerned by the freezing status
* `_amount` is the amount of tokens that are unfrozen
*/
event TokensUnfrozen(address indexed _userAddress, uint256 _amount);
/**
* this event is emitted when the token is paused
* the event is emitted by the pause function
* `_userAddress` is the address of the wallet that called the pause function
*/
event Paused(address _userAddress);
/**
* this event is emitted when the token is unpaused
* the event is emitted by the unpause function
* `_userAddress` is the address of the wallet that called the unpause function
*/
event Unpaused(address _userAddress);
/// functions
/**
* @dev sets the token name
* @param _name the name of token to set
* Only the owner of the token smart contract can call this function
* emits a `UpdatedTokenInformation` event
*/
function setName(string calldata _name) external;
/**
* @dev sets the token symbol
* @param _symbol the token symbol to set
* Only the owner of the token smart contract can call this function
* emits a `UpdatedTokenInformation` event
*/
function setSymbol(string calldata _symbol) external;
/**
* @dev sets the onchain ID of the token
* @param _onchainID the address of the onchain ID to set
* Only the owner of the token smart contract can call this function
* emits a `UpdatedTokenInformation` event
*/
function setOnchainID(address _onchainID) external;
/**
* @dev pauses the token contract, when contract is paused investors cannot transfer tokens anymore
* This function can only be called by a wallet set as agent of the token
* emits a `Paused` event
*/
function pause() external;
/**
* @dev unpauses the token contract, when contract is unpaused investors can transfer tokens
* if their wallet is not blocked & if the amount to transfer is <= to the amount of free tokens
* This function can only be called by a wallet set as agent of the token
* emits an `Unpaused` event
*/
function unpause() external;
/**
* @dev sets an address frozen status for this token.
* @param _userAddress The address for which to update frozen status
* @param _freeze Frozen status of the address
* This function can only be called by a wallet set as agent of the token
* emits an `AddressFrozen` event
*/
function setAddressFrozen(address _userAddress, bool _freeze) external;
/**
* @dev freezes token amount specified for given address.
* @param _userAddress The address for which to update frozen tokens
* @param _amount Amount of Tokens to be frozen
* This function can only be called by a wallet set as agent of the token
* emits a `TokensFrozen` event
*/
function freezePartialTokens(address _userAddress, uint256 _amount) external;
/**
* @dev unfreezes token amount specified for given address
* @param _userAddress The address for which to update frozen tokens
* @param _amount Amount of Tokens to be unfrozen
* This function can only be called by a wallet set as agent of the token
* emits a `TokensUnfrozen` event
*/
function unfreezePartialTokens(address _userAddress, uint256 _amount) external;
/**
* @dev sets the Identity Registry for the token
* @param _identityRegistry the address of the Identity Registry to set
* Only the owner of the token smart contract can call this function
* emits an `IdentityRegistryAdded` event
*/
function setIdentityRegistry(address _identityRegistry) external;
/**
* @dev sets the compliance contract of the token
* @param _compliance the address of the compliance contract to set
* Only the owner of the token smart contract can call this function
* calls bindToken on the compliance contract
* emits a `ComplianceAdded` event
*/
function setCompliance(address _compliance) external;
/**
* @dev force a transfer of tokens between 2 whitelisted wallets
* In case the `from` address has not enough free tokens (unfrozen tokens)
* but has a total balance higher or equal to the `amount`
* the amount of frozen tokens is reduced in order to have enough free tokens
* to proceed the transfer, in such a case, the remaining balance on the `from`
* account is 100% composed of frozen tokens post-transfer.
* Require that the `to` address is a verified address,
* @param _from The address of the sender
* @param _to The address of the receiver
* @param _amount The number of tokens to transfer
* @return `true` if successful and revert if unsuccessful
* This function can only be called by a wallet set as agent of the token
* emits a `TokensUnfrozen` event if `_amount` is higher than the free balance of `_from`
* emits a `Transfer` event
*/
function forcedTransfer(
address _from,
address _to,
uint256 _amount
) external returns (bool);
/**
* @dev mint tokens on a wallet
* Improved version of default mint method. Tokens can be minted
* to an address if only it is a verified address as per the security token.
* @param _to Address to mint the tokens to.
* @param _amount Amount of tokens to mint.
* This function can only be called by a wallet set as agent of the token
* emits a `Transfer` event
*/
function mint(address _to, uint256 _amount) external;
/**
* @dev burn tokens on a wallet
* In case the `account` address has not enough free tokens (unfrozen tokens)
* but has a total balance higher or equal to the `value` amount
* the amount of frozen tokens is reduced in order to have enough free tokens
* to proceed the burn, in such a case, the remaining balance on the `account`
* is 100% composed of frozen tokens post-transaction.
* @param _userAddress Address to burn the tokens from.
* @param _amount Amount of tokens to burn.
* This function can only be called by a wallet set as agent of the token
* emits a `TokensUnfrozen` event if `_amount` is higher than the free balance of `_userAddress`
* emits a `Transfer` event
*/
function burn(address _userAddress, uint256 _amount) external;
/**
* @dev recovery function used to force transfer tokens from a
* lost wallet to a new wallet for an investor.
* @param _lostWallet the wallet that the investor lost
* @param _newWallet the newly provided wallet on which tokens have to be transferred
* @param _investorOnchainID the onchainID of the investor asking for a recovery
* This function can only be called by a wallet set as agent of the token
* emits a `TokensUnfrozen` event if there is some frozen tokens on the lost wallet if the recovery process is successful
* emits a `Transfer` event if the recovery process is successful
* emits a `RecoverySuccess` event if the recovery process is successful
* emits a `RecoveryFails` event if the recovery process fails
*/
function recoveryAddress(
address _lostWallet,
address _newWallet,
address _investorOnchainID
) external returns (bool);
/**
* @dev function allowing to issue transfers in batch
* Require that the msg.sender and `to` addresses are not frozen.
* Require that the total value should not exceed available balance.
* Require that the `to` addresses are all verified addresses,
* IMPORTANT : THIS TRANSACTION COULD EXCEED GAS LIMIT IF `_toList.length` IS TOO HIGH,
* USE WITH CARE OR YOU COULD LOSE TX FEES WITH AN "OUT OF GAS" TRANSACTION
* @param _toList The addresses of the receivers
* @param _amounts The number of tokens to transfer to the corresponding receiver
* emits _toList.length `Transfer` events
*/
function batchTransfer(address[] calldata _toList, uint256[] calldata _amounts) external;
/**
* @dev function allowing to issue forced transfers in batch
* Require that `_amounts[i]` should not exceed available balance of `_fromList[i]`.
* Require that the `_toList` addresses are all verified addresses
* IMPORTANT : THIS TRANSACTION COULD EXCEED GAS LIMIT IF `_fromList.length` IS TOO HIGH,
* USE WITH CARE OR YOU COULD LOSE TX FEES WITH AN "OUT OF GAS" TRANSACTION
* @param _fromList The addresses of the senders
* @param _toList The addresses of the receivers
* @param _amounts The number of tokens to transfer to the corresponding receiver
* This function can only be called by a wallet set as agent of the token
* emits `TokensUnfrozen` events if `_amounts[i]` is higher than the free balance of `_fromList[i]`
* emits _fromList.length `Transfer` events
*/
function batchForcedTransfer(
address[] calldata _fromList,
address[] calldata _toList,
uint256[] calldata _amounts
) external;
/**
* @dev function allowing to mint tokens in batch
* Require that the `_toList` addresses are all verified addresses
* IMPORTANT : THIS TRANSACTION COULD EXCEED GAS LIMIT IF `_toList.length` IS TOO HIGH,
* USE WITH CARE OR YOU COULD LOSE TX FEES WITH AN "OUT OF GAS" TRANSACTION
* @param _toList The addresses of the receivers
* @param _amounts The number of tokens to mint to the corresponding receiver
* This function can only be called by a wallet set as agent of the token
* emits _toList.length `Transfer` events
*/
function batchMint(address[] calldata _toList, uint256[] calldata _amounts) external;
/**
* @dev function allowing to burn tokens in batch
* Require that the `_userAddresses` addresses are all verified addresses
* IMPORTANT : THIS TRANSACTION COULD EXCEED GAS LIMIT IF `_userAddresses.length` IS TOO HIGH,
* USE WITH CARE OR YOU COULD LOSE TX FEES WITH AN "OUT OF GAS" TRANSACTION
* @param _userAddresses The addresses of the wallets concerned by the burn
* @param _amounts The number of tokens to burn from the corresponding wallets
* This function can only be called by a wallet set as agent of the token
* emits _userAddresses.length `Transfer` events
*/
function batchBurn(address[] calldata _userAddresses, uint256[] calldata _amounts) external;
/**
* @dev function allowing to set frozen addresses in batch
* IMPORTANT : THIS TRANSACTION COULD EXCEED GAS LIMIT IF `_userAddresses.length` IS TOO HIGH,
* USE WITH CARE OR YOU COULD LOSE TX FEES WITH AN "OUT OF GAS" TRANSACTION
* @param _userAddresses The addresses for which to update frozen status
* @param _freeze Frozen status of the corresponding address
* This function can only be called by a wallet set as agent of the token
* emits _userAddresses.length `AddressFrozen` events
*/
function batchSetAddressFrozen(address[] calldata _userAddresses, bool[] calldata _freeze) external;
/**
* @dev function allowing to freeze tokens partially in batch
* IMPORTANT : THIS TRANSACTION COULD EXCEED GAS LIMIT IF `_userAddresses.length` IS TOO HIGH,
* USE WITH CARE OR YOU COULD LOSE TX FEES WITH AN "OUT OF GAS" TRANSACTION
* @param _userAddresses The addresses on which tokens need to be frozen
* @param _amounts the amount of tokens to freeze on the corresponding address
* This function can only be called by a wallet set as agent of the token
* emits _userAddresses.length `TokensFrozen` events
*/
function batchFreezePartialTokens(address[] calldata _userAddresses, uint256[] calldata _amounts) external;
/**
* @dev function allowing to unfreeze tokens partially in batch
* IMPORTANT : THIS TRANSACTION COULD EXCEED GAS LIMIT IF `_userAddresses.length` IS TOO HIGH,
* USE WITH CARE OR YOU COULD LOSE TX FEES WITH AN "OUT OF GAS" TRANSACTION
* @param _userAddresses The addresses on which tokens need to be unfrozen
* @param _amounts the amount of tokens to unfreeze on the corresponding address
* This function can only be called by a wallet set as agent of the token
* emits _userAddresses.length `TokensUnfrozen` events
*/
function batchUnfreezePartialTokens(address[] calldata _userAddresses, uint256[] calldata _amounts) external;
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5,05` (`505 / 1 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* balanceOf() and transfer().
*/
function decimals() external view returns (uint8);
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the address of the onchainID of the token.
* the onchainID of the token gives all the information available
* about the token and is managed by the token issuer or his agent.
*/
function onchainID() external view returns (address);
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the TREX version of the token.
* current version is 3.0.0
*/
function version() external view returns (string memory);
/**
* @dev Returns the Identity Registry linked to the token
*/
function identityRegistry() external view returns (IIdentityRegistry);
/**
* @dev Returns the Compliance contract linked to the token
*/
function compliance() external view returns (IModularCompliance);
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() external view returns (bool);
/**
* @dev Returns the freezing status of a wallet
* if isFrozen returns `true` the wallet is frozen
* if isFrozen returns `false` the wallet is not frozen
* isFrozen returning `true` doesn't mean that the balance is free, tokens could be blocked by
* a partial freeze or the whole token could be blocked by pause
* @param _userAddress the address of the wallet on which isFrozen is called
*/
function isFrozen(address _userAddress) external view returns (bool);
/**
* @dev Returns the amount of tokens that are partially frozen on a wallet
* the amount of frozen tokens is always <= to the total balance of the wallet
* @param _userAddress the address of the wallet on which getFrozenTokens is called
*/
function getFrozenTokens(address _userAddress) external view returns (uint256);
}
IProxy.sol 76 lines
// SPDX-License-Identifier: GPL-3.0
//
// :+#####%%%%%%%%%%%%%%+
// .-*@@@%+.:+%@@@@@%%#***%@@%=
// :=*%@@@#=. :#@@% *@@@%=
// .-+*%@%*-.:+%@@@@@@+. -*+: .=#. :%@@@%-
// :=*@@@@%%@@@@@@@@@%@@@- .=#@@@%@%= =@@@@#.
// -=+#%@@%#*=:. :%@@@@%. -*@@#*@@@@@@@#=:- *@@@@+
// =@@%=:. :=: *@@@@@%#- =%*%@@@@#+-. =+ :%@@@%-
// -@@%. .+@@@ =+=-. @@#- +@@@%- =@@@@%:
// :@@@. .+@@#%: : .=*=-::.-%@@@+*@@= +@@@@#.
// %@@: +@%%* =%@@@@@@@@@@@#. .*@%- +@@@@*.
// #@@= .+@@@@%:=*@@@@@- :%@%: .*@@@@+
// *@@* +@@@#-@@%-:%@@* +@@#. :%@@@@-
// -@@% .:-=++*##%%%@@@@@@@@@@@@*. :@+.@@@%: .#@@+ =@@@@#:
// .@@@*-+*#%%%@@@@@@@@@@@@@@@@%%#**@@%@@@. *@=*@@# :#@%= .#@@@@#-
// -%@@@@@@@@@@@@@@@*+==-:-@@@= *@# .#@*-=*@@@@%= -%@@@* =@@@@@%-
// -+%@@@#. %@%%= -@@:+@: -@@* *@@*-:: -%@@%=. .*@@@@@#
// *@@@* +@* *@@##@@- #@*@@+ -@@= . :+@@@#: .-+@@@%+-
// +@@@%*@@:..=@@@@* .@@@* .#@#. .=+- .=%@@@*. :+#@@@@*=:
// =@@@@%@@@@@@@@@@@@@@@@@@@@@@%- :+#*. :*@@@%=. .=#@@@@%+:
// .%@@= ..... .=#@@+. .#@@@*: -*%@@@@%+.
// +@@#+===---:::... .=%@@*- +@@@+. -*@@@@@%+.
// -@@@@@@@@@@@@@@@@@@@@@@%@@@@= -@@@+ -#@@@@@#=.
// ..:::---===+++***###%%%@@@#- .#@@+ -*@@@@@#=.
// @@@@@@+. +@@*. .+@@@@@%=.
// -@@@@@= =@@%: -#@@@@%+.
// +@@@@@. =@@@= .+@@@@@*:
// #@@@@#:%@@#. :*@@@@#-
// @@@@@%@@@= :#@@@@+.
// :@@@@@@@#.:#@@@%-
// +@@@@@@-.*@@@*:
// #@@@@#.=@@@+.
// @@@@+-%@%=
// :@@@#%@%=
// +@@@@%-
// :#%%=
//
/**
* NOTICE
*
* The T-REX software is licensed under a proprietary license or the GPL v.3.
* If you choose to receive it under the GPL v.3 license, the following applies:
* T-REX is a suite of smart contracts implementing the ERC-3643 standard and
* developed by Tokeny to manage and transfer financial assets on EVM blockchains
*
* Copyright (C) 2023, Tokeny sàrl.
*
* 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 <https://www.gnu.org/licenses/>.
*/
pragma solidity 0.8.17;
interface IProxy {
/// events
event ImplementationAuthoritySet(address indexed _implementationAuthority);
/// functions
function setImplementationAuthority(address _newImplementationAuthority) external;
function getImplementationAuthority() external view returns(address);
}
ITREXFactory.sol 175 lines
// SPDX-License-Identifier: GPL-3.0
//
// :+#####%%%%%%%%%%%%%%+
// .-*@@@%+.:+%@@@@@%%#***%@@%=
// :=*%@@@#=. :#@@% *@@@%=
// .-+*%@%*-.:+%@@@@@@+. -*+: .=#. :%@@@%-
// :=*@@@@%%@@@@@@@@@%@@@- .=#@@@%@%= =@@@@#.
// -=+#%@@%#*=:. :%@@@@%. -*@@#*@@@@@@@#=:- *@@@@+
// =@@%=:. :=: *@@@@@%#- =%*%@@@@#+-. =+ :%@@@%-
// -@@%. .+@@@ =+=-. @@#- +@@@%- =@@@@%:
// :@@@. .+@@#%: : .=*=-::.-%@@@+*@@= +@@@@#.
// %@@: +@%%* =%@@@@@@@@@@@#. .*@%- +@@@@*.
// #@@= .+@@@@%:=*@@@@@- :%@%: .*@@@@+
// *@@* +@@@#-@@%-:%@@* +@@#. :%@@@@-
// -@@% .:-=++*##%%%@@@@@@@@@@@@*. :@+.@@@%: .#@@+ =@@@@#:
// .@@@*-+*#%%%@@@@@@@@@@@@@@@@%%#**@@%@@@. *@=*@@# :#@%= .#@@@@#-
// -%@@@@@@@@@@@@@@@*+==-:-@@@= *@# .#@*-=*@@@@%= -%@@@* =@@@@@%-
// -+%@@@#. %@%%= -@@:+@: -@@* *@@*-:: -%@@%=. .*@@@@@#
// *@@@* +@* *@@##@@- #@*@@+ -@@= . :+@@@#: .-+@@@%+-
// +@@@%*@@:..=@@@@* .@@@* .#@#. .=+- .=%@@@*. :+#@@@@*=:
// =@@@@%@@@@@@@@@@@@@@@@@@@@@@%- :+#*. :*@@@%=. .=#@@@@%+:
// .%@@= ..... .=#@@+. .#@@@*: -*%@@@@%+.
// +@@#+===---:::... .=%@@*- +@@@+. -*@@@@@%+.
// -@@@@@@@@@@@@@@@@@@@@@@%@@@@= -@@@+ -#@@@@@#=.
// ..:::---===+++***###%%%@@@#- .#@@+ -*@@@@@#=.
// @@@@@@+. +@@*. .+@@@@@%=.
// -@@@@@= =@@%: -#@@@@%+.
// +@@@@@. =@@@= .+@@@@@*:
// #@@@@#:%@@#. :*@@@@#-
// @@@@@%@@@= :#@@@@+.
// :@@@@@@@#.:#@@@%-
// +@@@@@@-.*@@@*:
// #@@@@#.=@@@+.
// @@@@+-%@%=
// :@@@#%@%=
// +@@@@%-
// :#%%=
//
/**
* NOTICE
*
* The T-REX software is licensed under a proprietary license or the GPL v.3.
* If you choose to receive it under the GPL v.3 license, the following applies:
* T-REX is a suite of smart contracts implementing the ERC-3643 standard and
* developed by Tokeny to manage and transfer financial assets on EVM blockchains
*
* Copyright (C) 2023, Tokeny sàrl.
*
* 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 <https://www.gnu.org/licenses/>.
*/
pragma solidity 0.8.17;
interface ITREXFactory {
/// Types
struct TokenDetails {
// address of the owner of all contracts
address owner;
// name of the token
string name;
// symbol / ticker of the token
string symbol;
// decimals of the token (can be between 0 and 18)
uint8 decimals;
// identity registry storage address
// set it to ZERO address if you want to deploy a new storage
// if an address is provided, please ensure that the factory is set as owner of the contract
address irs;
// ONCHAINID of the token
// solhint-disable-next-line var-name-mixedcase
address ONCHAINID;
// list of agents of the identity registry (can be set to an AgentManager contract)
address[] irAgents;
// list of agents of the token
address[] tokenAgents;
// modules to bind to the compliance, indexes are corresponding to the settings callData indexes
// if a module doesn't require settings, it can be added at the end of the array, at index > settings.length
address[] complianceModules;
// settings calls for compliance modules
bytes[] complianceSettings;
}
struct ClaimDetails {
// claim topics required
uint256[] claimTopics;
// trusted issuers addresses
address[] issuers;
// claims that issuers are allowed to emit, by index, index corresponds to the `issuers` indexes
uint256[][] issuerClaims;
}
/// events
/// event emitted whenever a single contract is deployed by the factory
event Deployed(address indexed _addr);
/// event emitted when the implementation authority of the factory contract is set
event ImplementationAuthoritySet(address _implementationAuthority);
/// event emitted by the factory when a full suite of T-REX contracts is deployed
event TREXSuiteDeployed(address indexed _token, address _ir, address _irs, address _tir, address _ctr, address
_mc, string indexed _salt);
/// functions
/**
* @dev setter for implementation authority contract address
* the implementation authority contract contains the addresses of all implementation contracts
* the proxies created by the factory will use the different implementations available
* in the implementation authority contract
* Only owner can call.
* emits `ImplementationAuthoritySet` event
* @param _implementationAuthority The address of the implementation authority smart contract
*/
function setImplementationAuthority(address _implementationAuthority) external;
/**
* @dev function used to deploy a new TREX token and set all the parameters as required by the issuer paperwork
* this function will deploy and set the contracts as follow :
* Token : deploy the token contract (proxy) and set the name, symbol, ONCHAINID, decimals, owner, agents,
* IR address , Compliance address
* Identity Registry : deploy the IR contract (proxy) and set the owner, agents,
* IRS address, TIR address, CTR address
* IRS : deploy IRS contract (proxy) if required (address set as 0 in the TokenDetails, bind IRS to IR, set owner
* CTR : deploy CTR contract (proxy), set required claims, set owner
* TIR : deploy TIR contract (proxy), set trusted issuers, set owner
* Compliance: deploy modular compliance, bind with token, add modules, set modules parameters, set owner
* All contracts are deployed using CREATE2 opcode, and therefore are deployed at a predetermined address
* The address can be the same on all EVM blockchains as long as the factory address is the same as well
* Only owner can call.
* emits `TREXSuiteDeployed` event
* @param _salt the salt used to make the contracts deployments with CREATE2
* @param _tokenDetails The details of the token to deploy (see struct TokenDetails for more details)
* @param _claimDetails The details of the claims and claim issuers (see struct ClaimDetails for more details)
* cannot add more than 5 agents on IR and 5 agents on Token
* cannot add more than 5 claim topics required and more than 5 trusted issuers
* cannot add more than 30 compliance settings transactions
*/
function deployTREXSuite(
string memory _salt,
TokenDetails calldata _tokenDetails,
ClaimDetails calldata _claimDetails) external;
/**
* @dev function that can be used to recover the ownership of contracts owned by the factory
* typically used for IRS contracts owned by the factory (ownership of IRS is mandatory to call bind function)
* @param _contract The smart contract address
* @param _newOwner The address to transfer ownership to
* Only owner can call.
*/
function recoverContractOwnership(address _contract, address _newOwner) external;
/**
* @dev getter for implementation authority address
*/
function getImplementationAuthority() external view returns(address);
/**
* @dev getter for token address corresponding to salt string
* @param _salt The salt string that was used to deploy the token
*/
function getToken(string calldata _salt) external view returns(address);
}
IIAFactory.sol 91 lines
// SPDX-License-Identifier: GPL-3.0
//
// :+#####%%%%%%%%%%%%%%+
// .-*@@@%+.:+%@@@@@%%#***%@@%=
// :=*%@@@#=. :#@@% *@@@%=
// .-+*%@%*-.:+%@@@@@@+. -*+: .=#. :%@@@%-
// :=*@@@@%%@@@@@@@@@%@@@- .=#@@@%@%= =@@@@#.
// -=+#%@@%#*=:. :%@@@@%. -*@@#*@@@@@@@#=:- *@@@@+
// =@@%=:. :=: *@@@@@%#- =%*%@@@@#+-. =+ :%@@@%-
// -@@%. .+@@@ =+=-. @@#- +@@@%- =@@@@%:
// :@@@. .+@@#%: : .=*=-::.-%@@@+*@@= +@@@@#.
// %@@: +@%%* =%@@@@@@@@@@@#. .*@%- +@@@@*.
// #@@= .+@@@@%:=*@@@@@- :%@%: .*@@@@+
// *@@* +@@@#-@@%-:%@@* +@@#. :%@@@@-
// -@@% .:-=++*##%%%@@@@@@@@@@@@*. :@+.@@@%: .#@@+ =@@@@#:
// .@@@*-+*#%%%@@@@@@@@@@@@@@@@%%#**@@%@@@. *@=*@@# :#@%= .#@@@@#-
// -%@@@@@@@@@@@@@@@*+==-:-@@@= *@# .#@*-=*@@@@%= -%@@@* =@@@@@%-
// -+%@@@#. %@%%= -@@:+@: -@@* *@@*-:: -%@@%=. .*@@@@@#
// *@@@* +@* *@@##@@- #@*@@+ -@@= . :+@@@#: .-+@@@%+-
// +@@@%*@@:..=@@@@* .@@@* .#@#. .=+- .=%@@@*. :+#@@@@*=:
// =@@@@%@@@@@@@@@@@@@@@@@@@@@@%- :+#*. :*@@@%=. .=#@@@@%+:
// .%@@= ..... .=#@@+. .#@@@*: -*%@@@@%+.
// +@@#+===---:::... .=%@@*- +@@@+. -*@@@@@%+.
// -@@@@@@@@@@@@@@@@@@@@@@%@@@@= -@@@+ -#@@@@@#=.
// ..:::---===+++***###%%%@@@#- .#@@+ -*@@@@@#=.
// @@@@@@+. +@@*. .+@@@@@%=.
// -@@@@@= =@@%: -#@@@@%+.
// +@@@@@. =@@@= .+@@@@@*:
// #@@@@#:%@@#. :*@@@@#-
// @@@@@%@@@= :#@@@@+.
// :@@@@@@@#.:#@@@%-
// +@@@@@@-.*@@@*:
// #@@@@#.=@@@+.
// @@@@+-%@%=
// :@@@#%@%=
// +@@@@%-
// :#%%=
//
/**
* NOTICE
*
* The T-REX software is licensed under a proprietary license or the GPL v.3.
* If you choose to receive it under the GPL v.3 license, the following applies:
* T-REX is a suite of smart contracts implementing the ERC-3643 standard and
* developed by Tokeny to manage and transfer financial assets on EVM blockchains
*
* Copyright (C) 2023, Tokeny sàrl.
*
* 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 <https://www.gnu.org/licenses/>.
*/
pragma solidity 0.8.17;
interface IIAFactory {
/// events
/// event emitted when a new TREXImplementationAuthority is deployed
event ImplementationAuthorityDeployed(address indexed _ia);
/// functions
/**
* @dev deploy a new TREXImplementationAuthority smart contract
* @param _token the token for which the new IA will be used
* function called by the `changeImplementationAuthority` function
* can be called only by the reference TREXImplementationAuthority contract
* the new contract deployed will contain all the versions from reference IA
* the new contract will be set on the same version as the reference IA
* ownership of the new IA is transferred to the Owner of the token
* emits a `ImplementationAuthorityDeployed` event
* returns the address of the IA contract deployed
*/
function deployIA(address _token) external returns (address);
/**
* @dev function used to know if an IA contract was deployed by the factory or not
* @param _ia the address of TREXImplementationAuthority contract
*/
function deployedByFactory(address _ia) external view returns (bool);
}
Context.sol 24 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
IIdentityRegistry.sol 255 lines
// SPDX-License-Identifier: GPL-3.0
//
// :+#####%%%%%%%%%%%%%%+
// .-*@@@%+.:+%@@@@@%%#***%@@%=
// :=*%@@@#=. :#@@% *@@@%=
// .-+*%@%*-.:+%@@@@@@+. -*+: .=#. :%@@@%-
// :=*@@@@%%@@@@@@@@@%@@@- .=#@@@%@%= =@@@@#.
// -=+#%@@%#*=:. :%@@@@%. -*@@#*@@@@@@@#=:- *@@@@+
// =@@%=:. :=: *@@@@@%#- =%*%@@@@#+-. =+ :%@@@%-
// -@@%. .+@@@ =+=-. @@#- +@@@%- =@@@@%:
// :@@@. .+@@#%: : .=*=-::.-%@@@+*@@= +@@@@#.
// %@@: +@%%* =%@@@@@@@@@@@#. .*@%- +@@@@*.
// #@@= .+@@@@%:=*@@@@@- :%@%: .*@@@@+
// *@@* +@@@#-@@%-:%@@* +@@#. :%@@@@-
// -@@% .:-=++*##%%%@@@@@@@@@@@@*. :@+.@@@%: .#@@+ =@@@@#:
// .@@@*-+*#%%%@@@@@@@@@@@@@@@@%%#**@@%@@@. *@=*@@# :#@%= .#@@@@#-
// -%@@@@@@@@@@@@@@@*+==-:-@@@= *@# .#@*-=*@@@@%= -%@@@* =@@@@@%-
// -+%@@@#. %@%%= -@@:+@: -@@* *@@*-:: -%@@%=. .*@@@@@#
// *@@@* +@* *@@##@@- #@*@@+ -@@= . :+@@@#: .-+@@@%+-
// +@@@%*@@:..=@@@@* .@@@* .#@#. .=+- .=%@@@*. :+#@@@@*=:
// =@@@@%@@@@@@@@@@@@@@@@@@@@@@%- :+#*. :*@@@%=. .=#@@@@%+:
// .%@@= ..... .=#@@+. .#@@@*: -*%@@@@%+.
// +@@#+===---:::... .=%@@*- +@@@+. -*@@@@@%+.
// -@@@@@@@@@@@@@@@@@@@@@@%@@@@= -@@@+ -#@@@@@#=.
// ..:::---===+++***###%%%@@@#- .#@@+ -*@@@@@#=.
// @@@@@@+. +@@*. .+@@@@@%=.
// -@@@@@= =@@%: -#@@@@%+.
// +@@@@@. =@@@= .+@@@@@*:
// #@@@@#:%@@#. :*@@@@#-
// @@@@@%@@@= :#@@@@+.
// :@@@@@@@#.:#@@@%-
// +@@@@@@-.*@@@*:
// #@@@@#.=@@@+.
// @@@@+-%@%=
// :@@@#%@%=
// +@@@@%-
// :#%%=
//
/**
* NOTICE
*
* The T-REX software is licensed under a proprietary license or the GPL v.3.
* If you choose to receive it under the GPL v.3 license, the following applies:
* T-REX is a suite of smart contracts implementing the ERC-3643 standard and
* developed by Tokeny to manage and transfer financial assets on EVM blockchains
*
* Copyright (C) 2023, Tokeny sàrl.
*
* 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 <https://www.gnu.org/licenses/>.
*/
pragma solidity 0.8.17;
import "./ITrustedIssuersRegistry.sol";
import "./IClaimTopicsRegistry.sol";
import "./IIdentityRegistryStorage.sol";
import "@onchain-id/solidity/contracts/interface/IClaimIssuer.sol";
import "@onchain-id/solidity/contracts/interface/IIdentity.sol";
interface IIdentityRegistry {
/**
* this event is emitted when the ClaimTopicsRegistry has been set for the IdentityRegistry
* the event is emitted by the IdentityRegistry constructor
* `claimTopicsRegistry` is the address of the Claim Topics Registry contract
*/
event ClaimTopicsRegistrySet(address indexed claimTopicsRegistry);
/**
* this event is emitted when the IdentityRegistryStorage has been set for the IdentityRegistry
* the event is emitted by the IdentityRegistry constructor
* `identityStorage` is the address of the Identity Registry Storage contract
*/
event IdentityStorageSet(address indexed identityStorage);
/**
* this event is emitted when the TrustedIssuersRegistry has been set for the IdentityRegistry
* the event is emitted by the IdentityRegistry constructor
* `trustedIssuersRegistry` is the address of the Trusted Issuers Registry contract
*/
event TrustedIssuersRegistrySet(address indexed trustedIssuersRegistry);
/**
* this event is emitted when an Identity is registered into the Identity Registry.
* the event is emitted by the 'registerIdentity' function
* `investorAddress` is the address of the investor's wallet
* `identity` is the address of the Identity smart contract (onchainID)
*/
event IdentityRegistered(address indexed investorAddress, IIdentity indexed identity);
/**
* this event is emitted when an Identity is removed from the Identity Registry.
* the event is emitted by the 'deleteIdentity' function
* `investorAddress` is the address of the investor's wallet
* `identity` is the address of the Identity smart contract (onchainID)
*/
event IdentityRemoved(address indexed investorAddress, IIdentity indexed identity);
/**
* this event is emitted when an Identity has been updated
* the event is emitted by the 'updateIdentity' function
* `oldIdentity` is the old Identity contract's address to update
* `newIdentity` is the new Identity contract's
*/
event IdentityUpdated(IIdentity indexed oldIdentity, IIdentity indexed newIdentity);
/**
* this event is emitted when an Identity's country has been updated
* the event is emitted by the 'updateCountry' function
* `investorAddress` is the address on which the country has been updated
* `country` is the numeric code (ISO 3166-1) of the new country
*/
event CountryUpdated(address indexed investorAddress, uint16 indexed country);
/**
* @dev Register an identity contract corresponding to a user address.
* Requires that the user doesn't have an identity contract already registered.
* This function can only be called by a wallet set as agent of the smart contract
* @param _userAddress The address of the user
* @param _identity The address of the user's identity contract
* @param _country The country of the investor
* emits `IdentityRegistered` event
*/
function registerIdentity(
address _userAddress,
IIdentity _identity,
uint16 _country
) external;
/**
* @dev Removes an user from the identity registry.
* Requires that the user have an identity contract already deployed that will be deleted.
* This function can only be called by a wallet set as agent of the smart contract
* @param _userAddress The address of the user to be removed
* emits `IdentityRemoved` event
*/
function deleteIdentity(address _userAddress) external;
/**
* @dev Replace the actual identityRegistryStorage contract with a new one.
* This function can only be called by the wallet set as owner of the smart contract
* @param _identityRegistryStorage The address of the new Identity Registry Storage
* emits `IdentityStorageSet` event
*/
function setIdentityRegistryStorage(address _identityRegistryStorage) external;
/**
* @dev Replace the actual claimTopicsRegistry contract with a new one.
* This function can only be called by the wallet set as owner of the smart contract
* @param _claimTopicsRegistry The address of the new claim Topics Registry
* emits `ClaimTopicsRegistrySet` event
*/
function setClaimTopicsRegistry(address _claimTopicsRegistry) external;
/**
* @dev Replace the actual trustedIssuersRegistry contract with a new one.
* This function can only be called by the wallet set as owner of the smart contract
* @param _trustedIssuersRegistry The address of the new Trusted Issuers Registry
* emits `TrustedIssuersRegistrySet` event
*/
function setTrustedIssuersRegistry(address _trustedIssuersRegistry) external;
/**
* @dev Updates the country corresponding to a user address.
* Requires that the user should have an identity contract already deployed that will be replaced.
* This function can only be called by a wallet set as agent of the smart contract
* @param _userAddress The address of the user
* @param _country The new country of the user
* emits `CountryUpdated` event
*/
function updateCountry(address _userAddress, uint16 _country) external;
/**
* @dev Updates an identity contract corresponding to a user address.
* Requires that the user address should be the owner of the identity contract.
* Requires that the user should have an identity contract already deployed that will be replaced.
* This function can only be called by a wallet set as agent of the smart contract
* @param _userAddress The address of the user
* @param _identity The address of the user's new identity contract
* emits `IdentityUpdated` event
*/
function updateIdentity(address _userAddress, IIdentity _identity) external;
/**
* @dev function allowing to register identities in batch
* This function can only be called by a wallet set as agent of the smart contract
* Requires that none of the users has an identity contract already registered.
* IMPORTANT : THIS TRANSACTION COULD EXCEED GAS LIMIT IF `_userAddresses.length` IS TOO HIGH,
* USE WITH CARE OR YOU COULD LOSE TX FEES WITH AN "OUT OF GAS" TRANSACTION
* @param _userAddresses The addresses of the users
* @param _identities The addresses of the corresponding identity contracts
* @param _countries The countries of the corresponding investors
* emits _userAddresses.length `IdentityRegistered` events
*/
function batchRegisterIdentity(
address[] calldata _userAddresses,
IIdentity[] calldata _identities,
uint16[] calldata _countries
) external;
/**
* @dev This functions checks whether a wallet has its Identity registered or not
* in the Identity Registry.
* @param _userAddress The address of the user to be checked.
* @return 'True' if the address is contained in the Identity Registry, 'false' if not.
*/
function contains(address _userAddress) external view returns (bool);
/**
* @dev This functions checks whether an identity contract
* corresponding to the provided user address has the required claims or not based
* on the data fetched from trusted issuers registry and from the claim topics registry
* @param _userAddress The address of the user to be verified.
* @return 'True' if the address is verified, 'false' if not.
*/
function isVerified(address _userAddress) external view returns (bool);
/**
* @dev Returns the onchainID of an investor.
* @param _userAddress The wallet of the investor
*/
function identity(address _userAddress) external view returns (IIdentity);
/**
* @dev Returns the country code of an investor.
* @param _userAddress The wallet of the investor
*/
function investorCountry(address _userAddress) external view returns (uint16);
/**
* @dev Returns the IdentityRegistryStorage linked to the current IdentityRegistry.
*/
function identityStorage() external view returns (IIdentityRegistryStorage);
/**
* @dev Returns the TrustedIssuersRegistry linked to the current IdentityRegistry.
*/
function issuersRegistry() external view returns (ITrustedIssuersRegistry);
/**
* @dev Returns the ClaimTopicsRegistry linked to the current IdentityRegistry.
*/
function topicsRegistry() external view returns (IClaimTopicsRegistry);
}
IModularCompliance.sol 230 lines
// SPDX-License-Identifier: GPL-3.0
//
// :+#####%%%%%%%%%%%%%%+
// .-*@@@%+.:+%@@@@@%%#***%@@%=
// :=*%@@@#=. :#@@% *@@@%=
// .-+*%@%*-.:+%@@@@@@+. -*+: .=#. :%@@@%-
// :=*@@@@%%@@@@@@@@@%@@@- .=#@@@%@%= =@@@@#.
// -=+#%@@%#*=:. :%@@@@%. -*@@#*@@@@@@@#=:- *@@@@+
// =@@%=:. :=: *@@@@@%#- =%*%@@@@#+-. =+ :%@@@%-
// -@@%. .+@@@ =+=-. @@#- +@@@%- =@@@@%:
// :@@@. .+@@#%: : .=*=-::.-%@@@+*@@= +@@@@#.
// %@@: +@%%* =%@@@@@@@@@@@#. .*@%- +@@@@*.
// #@@= .+@@@@%:=*@@@@@- :%@%: .*@@@@+
// *@@* +@@@#-@@%-:%@@* +@@#. :%@@@@-
// -@@% .:-=++*##%%%@@@@@@@@@@@@*. :@+.@@@%: .#@@+ =@@@@#:
// .@@@*-+*#%%%@@@@@@@@@@@@@@@@%%#**@@%@@@. *@=*@@# :#@%= .#@@@@#-
// -%@@@@@@@@@@@@@@@*+==-:-@@@= *@# .#@*-=*@@@@%= -%@@@* =@@@@@%-
// -+%@@@#. %@%%= -@@:+@: -@@* *@@*-:: -%@@%=. .*@@@@@#
// *@@@* +@* *@@##@@- #@*@@+ -@@= . :+@@@#: .-+@@@%+-
// +@@@%*@@:..=@@@@* .@@@* .#@#. .=+- .=%@@@*. :+#@@@@*=:
// =@@@@%@@@@@@@@@@@@@@@@@@@@@@%- :+#*. :*@@@%=. .=#@@@@%+:
// .%@@= ..... .=#@@+. .#@@@*: -*%@@@@%+.
// +@@#+===---:::... .=%@@*- +@@@+. -*@@@@@%+.
// -@@@@@@@@@@@@@@@@@@@@@@%@@@@= -@@@+ -#@@@@@#=.
// ..:::---===+++***###%%%@@@#- .#@@+ -*@@@@@#=.
// @@@@@@+. +@@*. .+@@@@@%=.
// -@@@@@= =@@%: -#@@@@%+.
// +@@@@@. =@@@= .+@@@@@*:
// #@@@@#:%@@#. :*@@@@#-
// @@@@@%@@@= :#@@@@+.
// :@@@@@@@#.:#@@@%-
// +@@@@@@-.*@@@*:
// #@@@@#.=@@@+.
// @@@@+-%@%=
// :@@@#%@%=
// +@@@@%-
// :#%%=
//
/**
* NOTICE
*
* The T-REX software is licensed under a proprietary license or the GPL v.3.
* If you choose to receive it under the GPL v.3 license, the following applies:
* T-REX is a suite of smart contracts implementing the ERC-3643 standard and
* developed by Tokeny to manage and transfer financial assets on EVM blockchains
*
* Copyright (C) 2023, Tokeny sàrl.
*
* 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 <https://www.gnu.org/licenses/>.
*/
pragma solidity 0.8.17;
interface IModularCompliance {
/// events
/**
* @dev Event emitted for each executed interaction with a module contract.
* For gas efficiency, only the interaction calldata selector (first 4
* bytes) is included in the event. For interactions without calldata or
* whose calldata is shorter than 4 bytes, the selector will be `0`.
*/
event ModuleInteraction(address indexed target, bytes4 selector);
/**
* this event is emitted when a token has been bound to the compliance contract
* the event is emitted by the bindToken function
* `_token` is the address of the token to bind
*/
event TokenBound(address _token);
/**
* this event is emitted when a token has been unbound from the compliance contract
* the event is emitted by the unbindToken function
* `_token` is the address of the token to unbind
*/
event TokenUnbound(address _token);
/**
* this event is emitted when a module has been added to the list of modules bound to the compliance contract
* the event is emitted by the addModule function
* `_module` is the address of the compliance module
*/
event ModuleAdded(address indexed _module);
/**
* this event is emitted when a module has been removed from the list of modules bound to the compliance contract
* the event is emitted by the removeModule function
* `_module` is the address of the compliance module
*/
event ModuleRemoved(address indexed _module);
/// functions
/**
* @dev binds a token to the compliance contract
* @param _token address of the token to bind
* This function can be called ONLY by the owner of the compliance contract
* Emits a TokenBound event
*/
function bindToken(address _token) external;
/**
* @dev unbinds a token from the compliance contract
* @param _token address of the token to unbind
* This function can be called ONLY by the owner of the compliance contract
* Emits a TokenUnbound event
*/
function unbindToken(address _token) external;
/**
* @dev adds a module to the list of compliance modules
* @param _module address of the module to add
* there cannot be more than 25 modules bound to the modular compliance for gas cost reasons
* This function can be called ONLY by the owner of the compliance contract
* Emits a ModuleAdded event
*/
function addModule(address _module) external;
/**
* @dev removes a module from the list of compliance modules
* @param _module address of the module to remove
* This function can be called ONLY by the owner of the compliance contract
* Emits a ModuleRemoved event
*/
function removeModule(address _module) external;
/**
* @dev calls any function on bound modules
* can be called only on bound modules
* @param callData the bytecode for interaction with the module, abi encoded
* @param _module The address of the module
* This function can be called only by the modular compliance owner
* emits a `ModuleInteraction` event
*/
function callModuleFunction(bytes calldata callData, address _module) external;
/**
* @dev function called whenever tokens are transferred
* from one wallet to another
* this function can update state variables in the modules bound to the compliance
* these state variables being used by the module checks to decide if a transfer
* is compliant or not depending on the values stored in these state variables and on
* the parameters of the modules
* This function can be called ONLY by the token contract bound to the compliance
* @param _from The address of the sender
* @param _to The address of the receiver
* @param _amount The amount of tokens involved in the transfer
* This function calls moduleTransferAction() on each module bound to the compliance contract
*/
function transferred(
address _from,
address _to,
uint256 _amount
) external;
/**
* @dev function called whenever tokens are created on a wallet
* this function can update state variables in the modules bound to the compliance
* these state variables being used by the module checks to decide if a transfer
* is compliant or not depending on the values stored in these state variables and on
* the parameters of the modules
* This function can be called ONLY by the token contract bound to the compliance
* @param _to The address of the receiver
* @param _amount The amount of tokens involved in the minting
* This function calls moduleMintAction() on each module bound to the compliance contract
*/
function created(address _to, uint256 _amount) external;
/**
* @dev function called whenever tokens are destroyed from a wallet
* this function can update state variables in the modules bound to the compliance
* these state variables being used by the module checks to decide if a transfer
* is compliant or not depending on the values stored in these state variables and on
* the parameters of the modules
* This function can be called ONLY by the token contract bound to the compliance
* @param _from The address on which tokens are burnt
* @param _amount The amount of tokens involved in the burn
* This function calls moduleBurnAction() on each module bound to the compliance contract
*/
function destroyed(address _from, uint256 _amount) external;
/**
* @dev checks that the transfer is compliant.
* default compliance always returns true
* READ ONLY FUNCTION, this function cannot be used to increment
* counters, emit events, ...
* @param _from The address of the sender
* @param _to The address of the receiver
* @param _amount The amount of tokens involved in the transfer
* This function will call moduleCheck() on every module bound to the compliance
* If each of the module checks return TRUE, this function will return TRUE as well
* returns FALSE otherwise
*/
function canTransfer(
address _from,
address _to,
uint256 _amount
) external view returns (bool);
/**
* @dev getter for the modules bound to the compliance contract
* returns address array of module contracts bound to the compliance
*/
function getModules() external view returns (address[] memory);
/**
* @dev getter for the address of the token bound
* returns the address of the token
*/
function getTokenBound() external view returns (address);
/**
* @dev checks if a module is bound to the compliance contract
* returns true if module is bound, false otherwise
*/
function isModuleBound(address _module) external view returns (bool);
}
IERC20.sol 82 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
ITrustedIssuersRegistry.sol 162 lines
// SPDX-License-Identifier: GPL-3.0
//
// :+#####%%%%%%%%%%%%%%+
// .-*@@@%+.:+%@@@@@%%#***%@@%=
// :=*%@@@#=. :#@@% *@@@%=
// .-+*%@%*-.:+%@@@@@@+. -*+: .=#. :%@@@%-
// :=*@@@@%%@@@@@@@@@%@@@- .=#@@@%@%= =@@@@#.
// -=+#%@@%#*=:. :%@@@@%. -*@@#*@@@@@@@#=:- *@@@@+
// =@@%=:. :=: *@@@@@%#- =%*%@@@@#+-. =+ :%@@@%-
// -@@%. .+@@@ =+=-. @@#- +@@@%- =@@@@%:
// :@@@. .+@@#%: : .=*=-::.-%@@@+*@@= +@@@@#.
// %@@: +@%%* =%@@@@@@@@@@@#. .*@%- +@@@@*.
// #@@= .+@@@@%:=*@@@@@- :%@%: .*@@@@+
// *@@* +@@@#-@@%-:%@@* +@@#. :%@@@@-
// -@@% .:-=++*##%%%@@@@@@@@@@@@*. :@+.@@@%: .#@@+ =@@@@#:
// .@@@*-+*#%%%@@@@@@@@@@@@@@@@%%#**@@%@@@. *@=*@@# :#@%= .#@@@@#-
// -%@@@@@@@@@@@@@@@*+==-:-@@@= *@# .#@*-=*@@@@%= -%@@@* =@@@@@%-
// -+%@@@#. %@%%= -@@:+@: -@@* *@@*-:: -%@@%=. .*@@@@@#
// *@@@* +@* *@@##@@- #@*@@+ -@@= . :+@@@#: .-+@@@%+-
// +@@@%*@@:..=@@@@* .@@@* .#@#. .=+- .=%@@@*. :+#@@@@*=:
// =@@@@%@@@@@@@@@@@@@@@@@@@@@@%- :+#*. :*@@@%=. .=#@@@@%+:
// .%@@= ..... .=#@@+. .#@@@*: -*%@@@@%+.
// +@@#+===---:::... .=%@@*- +@@@+. -*@@@@@%+.
// -@@@@@@@@@@@@@@@@@@@@@@%@@@@= -@@@+ -#@@@@@#=.
// ..:::---===+++***###%%%@@@#- .#@@+ -*@@@@@#=.
// @@@@@@+. +@@*. .+@@@@@%=.
// -@@@@@= =@@%: -#@@@@%+.
// +@@@@@. =@@@= .+@@@@@*:
// #@@@@#:%@@#. :*@@@@#-
// @@@@@%@@@= :#@@@@+.
// :@@@@@@@#.:#@@@%-
// +@@@@@@-.*@@@*:
// #@@@@#.=@@@+.
// @@@@+-%@%=
// :@@@#%@%=
// +@@@@%-
// :#%%=
//
/**
* NOTICE
*
* The T-REX software is licensed under a proprietary license or the GPL v.3.
* If you choose to receive it under the GPL v.3 license, the following applies:
* T-REX is a suite of smart contracts implementing the ERC-3643 standard and
* developed by Tokeny to manage and transfer financial assets on EVM blockchains
*
* Copyright (C) 2023, Tokeny sàrl.
*
* 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 <https://www.gnu.org/licenses/>.
*/
pragma solidity 0.8.17;
import "@onchain-id/solidity/contracts/interface/IClaimIssuer.sol";
interface ITrustedIssuersRegistry {
/**
* this event is emitted when a trusted issuer is added in the registry.
* the event is emitted by the addTrustedIssuer function
* `trustedIssuer` is the address of the trusted issuer's ClaimIssuer contract
* `claimTopics` is the set of claims that the trusted issuer is allowed to emit
*/
event TrustedIssuerAdded(IClaimIssuer indexed trustedIssuer, uint256[] claimTopics);
/**
* this event is emitted when a trusted issuer is removed from the registry.
* the event is emitted by the removeTrustedIssuer function
* `trustedIssuer` is the address of the trusted issuer's ClaimIssuer contract
*/
event TrustedIssuerRemoved(IClaimIssuer indexed trustedIssuer);
/**
* this event is emitted when the set of claim topics is changed for a given trusted issuer.
* the event is emitted by the updateIssuerClaimTopics function
* `trustedIssuer` is the address of the trusted issuer's ClaimIssuer contract
* `claimTopics` is the set of claims that the trusted issuer is allowed to emit
*/
event ClaimTopicsUpdated(IClaimIssuer indexed trustedIssuer, uint256[] claimTopics);
/**
* @dev registers a ClaimIssuer contract as trusted claim issuer.
* Requires that a ClaimIssuer contract doesn't already exist
* Requires that the claimTopics set is not empty
* Requires that there is no more than 15 claimTopics
* Requires that there is no more than 50 Trusted issuers
* @param _trustedIssuer The ClaimIssuer contract address of the trusted claim issuer.
* @param _claimTopics the set of claim topics that the trusted issuer is allowed to emit
* This function can only be called by the owner of the Trusted Issuers Registry contract
* emits a `TrustedIssuerAdded` event
*/
function addTrustedIssuer(IClaimIssuer _trustedIssuer, uint256[] calldata _claimTopics) external;
/**
* @dev Removes the ClaimIssuer contract of a trusted claim issuer.
* Requires that the claim issuer contract to be registered first
* @param _trustedIssuer the claim issuer to remove.
* This function can only be called by the owner of the Trusted Issuers Registry contract
* emits a `TrustedIssuerRemoved` event
*/
function removeTrustedIssuer(IClaimIssuer _trustedIssuer) external;
/**
* @dev Updates the set of claim topics that a trusted issuer is allowed to emit.
* Requires that this ClaimIssuer contract already exists in the registry
* Requires that the provided claimTopics set is not empty
* Requires that there is no more than 15 claimTopics
* @param _trustedIssuer the claim issuer to update.
* @param _claimTopics the set of claim topics that the trusted issuer is allowed to emit
* This function can only be called by the owner of the Trusted Issuers Registry contract
* emits a `ClaimTopicsUpdated` event
*/
function updateIssuerClaimTopics(IClaimIssuer _trustedIssuer, uint256[] calldata _claimTopics) external;
/**
* @dev Function for getting all the trusted claim issuers stored.
* @return array of all claim issuers registered.
*/
function getTrustedIssuers() external view returns (IClaimIssuer[] memory);
/**
* @dev Function for getting all the trusted issuer allowed for a given claim topic.
* @param claimTopic the claim topic to get the trusted issuers for.
* @return array of all claim issuer addresses that are allowed for the given claim topic.
*/
function getTrustedIssuersForClaimTopic(uint256 claimTopic) external view returns (IClaimIssuer[] memory);
/**
* @dev Checks if the ClaimIssuer contract is trusted
* @param _issuer the address of the ClaimIssuer contract
* @return true if the issuer is trusted, false otherwise.
*/
function isTrustedIssuer(address _issuer) external view returns (bool);
/**
* @dev Function for getting all the claim topic of trusted claim issuer
* Requires the provided ClaimIssuer contract to be registered in the trusted issuers registry.
* @param _trustedIssuer the trusted issuer concerned.
* @return The set of claim topics that the trusted issuer is allowed to emit
*/
function getTrustedIssuerClaimTopics(IClaimIssuer _trustedIssuer) external view returns (uint256[] memory);
/**
* @dev Function for checking if the trusted claim issuer is allowed
* to emit a certain claim topic
* @param _issuer the address of the trusted issuer's ClaimIssuer contract
* @param _claimTopic the Claim Topic that has to be checked to know if the `issuer` is allowed to emit it
* @return true if the issuer is trusted for this claim topic.
*/
function hasClaimTopic(address _issuer, uint256 _claimTopic) external view returns (bool);
}
IClaimTopicsRegistry.sol 102 lines
// SPDX-License-Identifier: GPL-3.0
//
// :+#####%%%%%%%%%%%%%%+
// .-*@@@%+.:+%@@@@@%%#***%@@%=
// :=*%@@@#=. :#@@% *@@@%=
// .-+*%@%*-.:+%@@@@@@+. -*+: .=#. :%@@@%-
// :=*@@@@%%@@@@@@@@@%@@@- .=#@@@%@%= =@@@@#.
// -=+#%@@%#*=:. :%@@@@%. -*@@#*@@@@@@@#=:- *@@@@+
// =@@%=:. :=: *@@@@@%#- =%*%@@@@#+-. =+ :%@@@%-
// -@@%. .+@@@ =+=-. @@#- +@@@%- =@@@@%:
// :@@@. .+@@#%: : .=*=-::.-%@@@+*@@= +@@@@#.
// %@@: +@%%* =%@@@@@@@@@@@#. .*@%- +@@@@*.
// #@@= .+@@@@%:=*@@@@@- :%@%: .*@@@@+
// *@@* +@@@#-@@%-:%@@* +@@#. :%@@@@-
// -@@% .:-=++*##%%%@@@@@@@@@@@@*. :@+.@@@%: .#@@+ =@@@@#:
// .@@@*-+*#%%%@@@@@@@@@@@@@@@@%%#**@@%@@@. *@=*@@# :#@%= .#@@@@#-
// -%@@@@@@@@@@@@@@@*+==-:-@@@= *@# .#@*-=*@@@@%= -%@@@* =@@@@@%-
// -+%@@@#. %@%%= -@@:+@: -@@* *@@*-:: -%@@%=. .*@@@@@#
// *@@@* +@* *@@##@@- #@*@@+ -@@= . :+@@@#: .-+@@@%+-
// +@@@%*@@:..=@@@@* .@@@* .#@#. .=+- .=%@@@*. :+#@@@@*=:
// =@@@@%@@@@@@@@@@@@@@@@@@@@@@%- :+#*. :*@@@%=. .=#@@@@%+:
// .%@@= ..... .=#@@+. .#@@@*: -*%@@@@%+.
// +@@#+===---:::... .=%@@*- +@@@+. -*@@@@@%+.
// -@@@@@@@@@@@@@@@@@@@@@@%@@@@= -@@@+ -#@@@@@#=.
// ..:::---===+++***###%%%@@@#- .#@@+ -*@@@@@#=.
// @@@@@@+. +@@*. .+@@@@@%=.
// -@@@@@= =@@%: -#@@@@%+.
// +@@@@@. =@@@= .+@@@@@*:
// #@@@@#:%@@#. :*@@@@#-
// @@@@@%@@@= :#@@@@+.
// :@@@@@@@#.:#@@@%-
// +@@@@@@-.*@@@*:
// #@@@@#.=@@@+.
// @@@@+-%@%=
// :@@@#%@%=
// +@@@@%-
// :#%%=
//
/**
* NOTICE
*
* The T-REX software is licensed under a proprietary license or the GPL v.3.
* If you choose to receive it under the GPL v.3 license, the following applies:
* T-REX is a suite of smart contracts implementing the ERC-3643 standard and
* developed by Tokeny to manage and transfer financial assets on EVM blockchains
*
* Copyright (C) 2023, Tokeny sàrl.
*
* 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 <https://www.gnu.org/licenses/>.
*/
pragma solidity 0.8.17;
interface IClaimTopicsRegistry {
/**
* this event is emitted when a claim topic has been added to the ClaimTopicsRegistry
* the event is emitted by the 'addClaimTopic' function
* `claimTopic` is the required claim added to the Claim Topics Registry
*/
event ClaimTopicAdded(uint256 indexed claimTopic);
/**
* this event is emitted when a claim topic has been removed from the ClaimTopicsRegistry
* the event is emitted by the 'removeClaimTopic' function
* `claimTopic` is the required claim removed from the Claim Topics Registry
*/
event ClaimTopicRemoved(uint256 indexed claimTopic);
/**
* @dev Add a trusted claim topic (For example: KYC=1, AML=2).
* Only owner can call.
* emits `ClaimTopicAdded` event
* cannot add more than 15 topics for 1 token as adding more could create gas issues
* @param _claimTopic The claim topic index
*/
function addClaimTopic(uint256 _claimTopic) external;
/**
* @dev Remove a trusted claim topic (For example: KYC=1, AML=2).
* Only owner can call.
* emits `ClaimTopicRemoved` event
* @param _claimTopic The claim topic index
*/
function removeClaimTopic(uint256 _claimTopic) external;
/**
* @dev Get the trusted claim topics for the security token
* @return Array of trusted claim topics
*/
function getClaimTopics() external view returns (uint256[] memory);
}
IIdentityRegistryStorage.sol 197 lines
// SPDX-License-Identifier: GPL-3.0
//
// :+#####%%%%%%%%%%%%%%+
// .-*@@@%+.:+%@@@@@%%#***%@@%=
// :=*%@@@#=. :#@@% *@@@%=
// .-+*%@%*-.:+%@@@@@@+. -*+: .=#. :%@@@%-
// :=*@@@@%%@@@@@@@@@%@@@- .=#@@@%@%= =@@@@#.
// -=+#%@@%#*=:. :%@@@@%. -*@@#*@@@@@@@#=:- *@@@@+
// =@@%=:. :=: *@@@@@%#- =%*%@@@@#+-. =+ :%@@@%-
// -@@%. .+@@@ =+=-. @@#- +@@@%- =@@@@%:
// :@@@. .+@@#%: : .=*=-::.-%@@@+*@@= +@@@@#.
// %@@: +@%%* =%@@@@@@@@@@@#. .*@%- +@@@@*.
// #@@= .+@@@@%:=*@@@@@- :%@%: .*@@@@+
// *@@* +@@@#-@@%-:%@@* +@@#. :%@@@@-
// -@@% .:-=++*##%%%@@@@@@@@@@@@*. :@+.@@@%: .#@@+ =@@@@#:
// .@@@*-+*#%%%@@@@@@@@@@@@@@@@%%#**@@%@@@. *@=*@@# :#@%= .#@@@@#-
// -%@@@@@@@@@@@@@@@*+==-:-@@@= *@# .#@*-=*@@@@%= -%@@@* =@@@@@%-
// -+%@@@#. %@%%= -@@:+@: -@@* *@@*-:: -%@@%=. .*@@@@@#
// *@@@* +@* *@@##@@- #@*@@+ -@@= . :+@@@#: .-+@@@%+-
// +@@@%*@@:..=@@@@* .@@@* .#@#. .=+- .=%@@@*. :+#@@@@*=:
// =@@@@%@@@@@@@@@@@@@@@@@@@@@@%- :+#*. :*@@@%=. .=#@@@@%+:
// .%@@= ..... .=#@@+. .#@@@*: -*%@@@@%+.
// +@@#+===---:::... .=%@@*- +@@@+. -*@@@@@%+.
// -@@@@@@@@@@@@@@@@@@@@@@%@@@@= -@@@+ -#@@@@@#=.
// ..:::---===+++***###%%%@@@#- .#@@+ -*@@@@@#=.
// @@@@@@+. +@@*. .+@@@@@%=.
// -@@@@@= =@@%: -#@@@@%+.
// +@@@@@. =@@@= .+@@@@@*:
// #@@@@#:%@@#. :*@@@@#-
// @@@@@%@@@= :#@@@@+.
// :@@@@@@@#.:#@@@%-
// +@@@@@@-.*@@@*:
// #@@@@#.=@@@+.
// @@@@+-%@%=
// :@@@#%@%=
// +@@@@%-
// :#%%=
//
/**
* NOTICE
*
* The T-REX software is licensed under a proprietary license or the GPL v.3.
* If you choose to receive it under the GPL v.3 license, the following applies:
* T-REX is a suite of smart contracts implementing the ERC-3643 standard and
* developed by Tokeny to manage and transfer financial assets on EVM blockchains
*
* Copyright (C) 2023, Tokeny sàrl.
*
* 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 <https://www.gnu.org/licenses/>.
*/
pragma solidity 0.8.17;
import "@onchain-id/solidity/contracts/interface/IIdentity.sol";
interface IIdentityRegistryStorage {
/// events
/**
* this event is emitted when an Identity is registered into the storage contract.
* the event is emitted by the 'registerIdentity' function
* `investorAddress` is the address of the investor's wallet
* `identity` is the address of the Identity smart contract (onchainID)
*/
event IdentityStored(address indexed investorAddress, IIdentity indexed identity);
/**
* this event is emitted when an Identity is removed from the storage contract.
* the event is emitted by the 'deleteIdentity' function
* `investorAddress` is the address of the investor's wallet
* `identity` is the address of the Identity smart contract (onchainID)
*/
event IdentityUnstored(address indexed investorAddress, IIdentity indexed identity);
/**
* this event is emitted when an Identity has been updated
* the event is emitted by the 'updateIdentity' function
* `oldIdentity` is the old Identity contract's address to update
* `newIdentity` is the new Identity contract's
*/
event IdentityModified(IIdentity indexed oldIdentity, IIdentity indexed newIdentity);
/**
* this event is emitted when an Identity's country has been updated
* the event is emitted by the 'updateCountry' function
* `investorAddress` is the address on which the country has been updated
* `country` is the numeric code (ISO 3166-1) of the new country
*/
event CountryModified(address indexed investorAddress, uint16 indexed country);
/**
* this event is emitted when an Identity Registry is bound to the storage contract
* the event is emitted by the 'addIdentityRegistry' function
* `identityRegistry` is the address of the identity registry added
*/
event IdentityRegistryBound(address indexed identityRegistry);
/**
* this event is emitted when an Identity Registry is unbound from the storage contract
* the event is emitted by the 'removeIdentityRegistry' function
* `identityRegistry` is the address of the identity registry removed
*/
event IdentityRegistryUnbound(address indexed identityRegistry);
/// functions
/**
* @dev adds an identity contract corresponding to a user address in the storage.
* Requires that the user doesn't have an identity contract already registered.
* This function can only be called by an address set as agent of the smart contract
* @param _userAddress The address of the user
* @param _identity The address of the user's identity contract
* @param _country The country of the investor
* emits `IdentityStored` event
*/
function addIdentityToStorage(
address _userAddress,
IIdentity _identity,
uint16 _country
) external;
/**
* @dev Removes an user from the storage.
* Requires that the user have an identity contract already deployed that will be deleted.
* This function can only be called by an address set as agent of the smart contract
* @param _userAddress The address of the user to be removed
* emits `IdentityUnstored` event
*/
function removeIdentityFromStorage(address _userAddress) external;
/**
* @dev Updates the country corresponding to a user address.
* Requires that the user should have an identity contract already deployed that will be replaced.
* This function can only be called by an address set as agent of the smart contract
* @param _userAddress The address of the user
* @param _country The new country of the user
* emits `CountryModified` event
*/
function modifyStoredInvestorCountry(address _userAddress, uint16 _country) external;
/**
* @dev Updates an identity contract corresponding to a user address.
* Requires that the user address should be the owner of the identity contract.
* Requires that the user should have an identity contract already deployed that will be replaced.
* This function can only be called by an address set as agent of the smart contract
* @param _userAddress The address of the user
* @param _identity The address of the user's new identity contract
* emits `IdentityModified` event
*/
function modifyStoredIdentity(address _userAddress, IIdentity _identity) external;
/**
* @notice Adds an identity registry as agent of the Identity Registry Storage Contract.
* This function can only be called by the wallet set as owner of the smart contract
* This function adds the identity registry to the list of identityRegistries linked to the storage contract
* cannot bind more than 300 IR to 1 IRS
* @param _identityRegistry The identity registry address to add.
*/
function bindIdentityRegistry(address _identityRegistry) external;
/**
* @notice Removes an identity registry from being agent of the Identity Registry Storage Contract.
* This function can only be called by the wallet set as owner of the smart contract
* This function removes the identity registry from the list of identityRegistries linked to the storage contract
* @param _identityRegistry The identity registry address to remove.
*/
function unbindIdentityRegistry(address _identityRegistry) external;
/**
* @dev Returns the identity registries linked to the storage contract
*/
function linkedIdentityRegistries() external view returns (address[] memory);
/**
* @dev Returns the onchainID of an investor.
* @param _userAddress The wallet of the investor
*/
function storedIdentity(address _userAddress) external view returns (IIdentity);
/**
* @dev Returns the country code of an investor.
* @param _userAddress The wallet of the investor
*/
function storedInvestorCountry(address _userAddress) external view returns (uint16);
}
IClaimIssuer.sol 59 lines
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;
import "./IIdentity.sol";
interface IClaimIssuer is IIdentity {
/**
* @dev Emitted when a claim is revoked.
*
* Specification: MUST be triggered when revoking a claim.
*/
event ClaimRevoked(bytes indexed signature);
/**
* @dev Revoke a claim previously issued, the claim is no longer considered as valid after revocation.
* @notice will fetch the claim from the identity contract (unsafe).
* @param _claimId the id of the claim
* @param _identity the address of the identity contract
* @return isRevoked true when the claim is revoked
*/
function revokeClaim(bytes32 _claimId, address _identity) external returns(bool);
/**
* @dev Revoke a claim previously issued, the claim is no longer considered as valid after revocation.
* @param signature the signature of the claim
*/
function revokeClaimBySignature(bytes calldata signature) external;
/**
* @dev Returns revocation status of a claim.
* @param _sig the signature of the claim
* @return isRevoked true if the claim is revoked and false otherwise
*/
function isClaimRevoked(bytes calldata _sig) external view returns (bool);
/**
* @dev Checks if a claim is valid.
* @param _identity the identity contract related to the claim
* @param claimTopic the claim topic of the claim
* @param sig the signature of the claim
* @param data the data field of the claim
* @return claimValid true if the claim is valid, false otherwise
*/
function isClaimValid(
IIdentity _identity,
uint256 claimTopic,
bytes calldata sig,
bytes calldata data)
external view returns (bool);
/**
* @dev returns the address that signed the given data
* @param sig the signature of the data
* @param dataHash the data that was signed
* returns the address that signed dataHash and created the signature sig
*/
function getRecoveredAddress(bytes calldata sig, bytes32 dataHash) external pure returns (address);
}
IIdentity.sol 8 lines
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;
import "./IERC734.sol";
import "./IERC735.sol";
// solhint-disable-next-line no-empty-blocks
interface IIdentity is IERC734, IERC735 {}
IERC734.sol 111 lines
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;
/**
* @dev interface of the ERC734 (Key Holder) standard as defined in the EIP.
*/
interface IERC734 {
/**
* @dev Emitted when an execution request was approved.
*
* Specification: MUST be triggered when approve was successfully called.
*/
event Approved(uint256 indexed executionId, bool approved);
/**
* @dev Emitted when an execute operation was approved and successfully performed.
*
* Specification: MUST be triggered when approve was called and the execution was successfully approved.
*/
event Executed(uint256 indexed executionId, address indexed to, uint256 indexed value, bytes data);
/**
* @dev Emitted when an execution request was performed via `execute`.
*
* Specification: MUST be triggered when execute was successfully called.
*/
event ExecutionRequested(uint256 indexed executionId, address indexed to, uint256 indexed value, bytes data);
/**
* @dev Emitted when an execute operation was called and failed
*
* Specification: MUST be triggered when execute call failed
*/
event ExecutionFailed(uint256 indexed executionId, address indexed to, uint256 indexed value, bytes data);
/**
* @dev Emitted when a key was added to the Identity.
*
* Specification: MUST be triggered when addKey was successfully called.
*/
event KeyAdded(bytes32 indexed key, uint256 indexed purpose, uint256 indexed keyType);
/**
* @dev Emitted when a key was removed from the Identity.
*
* Specification: MUST be triggered when removeKey was successfully called.
*/
event KeyRemoved(bytes32 indexed key, uint256 indexed purpose, uint256 indexed keyType);
/**
* @dev Adds a _key to the identity. The _purpose specifies the purpose of the key.
*
* Triggers Event: `KeyAdded`
*
* Specification: MUST only be done by keys of purpose 1, or the identity
* itself. If it's the identity itself, the approval process will determine its approval.
*/
function addKey(bytes32 _key, uint256 _purpose, uint256 _keyType) external returns (bool success);
/**
* @dev Approves an execution.
*
* Triggers Event: `Approved`
* Triggers on execution successful Event: `Executed`
* Triggers on execution failure Event: `ExecutionFailed`
*/
function approve(uint256 _id, bool _approve) external returns (bool success);
/**
* @dev Removes _purpose for _key from the identity.
*
* Triggers Event: `KeyRemoved`
*
* Specification: MUST only be done by keys of purpose 1, or the identity itself.
* If it's the identity itself, the approval process will determine its approval.
*/
function removeKey(bytes32 _key, uint256 _purpose) external returns (bool success);
/**
* @dev Passes an execution instruction to an ERC734 identity.
* How the execution is handled is up to the identity implementation:
* An execution COULD be requested and require `approve` to be called with one or more keys of purpose 1 or 2 to
* approve this execution.
* Execute COULD be used as the only accessor for `addKey` and `removeKey`.
*
* Triggers Event: ExecutionRequested
* Triggers on direct execution Event: Executed
*/
function execute(address _to, uint256 _value, bytes calldata _data) external payable returns (uint256 executionId);
/**
* @dev Returns the full key data, if present in the identity.
*/
function getKey(bytes32 _key) external view returns (uint256[] memory purposes, uint256 keyType, bytes32 key);
/**
* @dev Returns the list of purposes associated with a key.
*/
function getKeyPurposes(bytes32 _key) external view returns(uint256[] memory _purposes);
/**
* @dev Returns an array of public key bytes32 held by this identity.
*/
function getKeysByPurpose(uint256 _purpose) external view returns (bytes32[] memory keys);
/**
* @dev Returns TRUE if a key is present and has the given purpose. If the key is not present it returns FALSE.
*/
function keyHasPurpose(bytes32 _key, uint256 _purpose) external view returns (bool exists);
}
IERC735.sol 98 lines
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;
/**
* @dev interface of the ERC735 (Claim Holder) standard as defined in the EIP.
*/
interface IERC735 {
/**
* @dev Emitted when a claim was added.
*
* Specification: MUST be triggered when a claim was successfully added.
*/
event ClaimAdded(
bytes32 indexed claimId,
uint256 indexed topic,
uint256 scheme,
address indexed issuer,
bytes signature,
bytes data,
string uri);
/**
* @dev Emitted when a claim was removed.
*
* Specification: MUST be triggered when removeClaim was successfully called.
*/
event ClaimRemoved(
bytes32 indexed claimId,
uint256 indexed topic,
uint256 scheme,
address indexed issuer,
bytes signature,
bytes data,
string uri);
/**
* @dev Emitted when a claim was changed.
*
* Specification: MUST be triggered when addClaim was successfully called on an existing claimId.
*/
event ClaimChanged(
bytes32 indexed claimId,
uint256 indexed topic,
uint256 scheme,
address indexed issuer,
bytes signature,
bytes data,
string uri);
/**
* @dev Add or update a claim.
*
* Triggers Event: `ClaimAdded`, `ClaimChanged`
*
* Specification: Add or update a claim from an issuer.
*
* _signature is a signed message of the following structure:
* `keccak256(abi.encode(address identityHolder_address, uint256 topic, bytes data))`.
* Claim IDs are generated using `keccak256(abi.encode(address issuer_address + uint256 topic))`.
*/
function addClaim(
uint256 _topic,
uint256 _scheme,
address issuer,
bytes calldata _signature,
bytes calldata _data,
string calldata _uri)
external returns (bytes32 claimRequestId);
/**
* @dev Removes a claim.
*
* Triggers Event: `ClaimRemoved`
*
* Claim IDs are generated using `keccak256(abi.encode(address issuer_address, uint256 topic))`.
*/
function removeClaim(bytes32 _claimId) external returns (bool success);
/**
* @dev Get a claim by its ID.
*
* Claim IDs are generated using `keccak256(abi.encode(address issuer_address, uint256 topic))`.
*/
function getClaim(bytes32 _claimId)
external view returns(
uint256 topic,
uint256 scheme,
address issuer,
bytes memory signature,
bytes memory data,
string memory uri);
/**
* @dev Returns an array of claim IDs by topic.
*/
function getClaimIdsByTopic(uint256 _topic) external view returns(bytes32[] memory claimIds);
}
Read Contract
getCTRImplementation 0x6ff6e83f → address
getContracts 0xdb5835ce → tuple
getCurrentVersion 0xfabec44a → tuple
getIRImplementation 0x1ee9ce8b → address
getIRSImplementation 0x9e3e7bb9 → address
getMCImplementation 0x61f89825 → address
getReferenceContract 0xcd24be22 → address
getTIRImplementation 0xfedcc052 → address
getTREXFactory 0x2c5d4f8e → address
getTokenImplementation 0x709bc7f3 → address
isReferenceContract 0x1320a65a → bool
owner 0x8da5cb5b → address
Write Contract 9 functions
These functions modify contract state and require a wallet transaction to execute.
addAndUseTREXVersion 0x9b0898fa
tuple _version
tuple _trex
addTREXVersion 0x3225e283
tuple _version
tuple _trex
changeImplementationAuthority 0x7f82a5e7
address _token
address _newImplementationAuthority
fetchVersion 0x80237ca0
tuple _version
renounceOwnership 0x715018a6
No parameters
setIAFactory 0xcf49020e
address iaFactory
setTREXFactory 0x6df23789
address trexFactory
transferOwnership 0xf2fde38b
address newOwner
useTREXVersion 0x6c93f637
tuple _version
Recent Transactions
No transactions found for this address