This repository provides an implementation of Whitelist interface proposed in the TZIP-15 written in SmartPy: Python library for constructing Tezos SC and compiled to Michelson code. The contract is migrated from the Lorentz whitelisting contract.
๐ก Why a whitelist contract?
The purpose of the Whitelist contract is to validate transfers so the token's contract holder can control which users can perform such operations. The Whitelist contract contains a list of users and entities that have satisfied the euroTz KYC/AML compliance procedures and thus are eligible to hold euroTz Tokens.
๐ Specifications
UserID
As userID, we use the user's public key hash, e.g. a tz1 address.
The whitelist contract is deployed separately from our euroTz contract.
The assertion entrypoints are called from euroTz contract, without requiring callbacks since they call FAILWITH when they fail.
How does our wrapper whitelist SC work?
๐ฅ Main scenarios:
Issuer may transfer to bobONLY if bob's is an asserted receiver, in other words, bob must be added to the users big_map and his whitelistID must be set and unrestricted in the whitelists big_map.
Alice may transfer to BobONLY if bob and Alice are asserted users AND Bob's whitelistID is in Alice's allowedWhitelists.
โฌ๏ธ Get the Project:
Clone the project & cd to the directory;
Install the packages with yarn install.
๐ EntryPoints (SC methods):
Visit TZIP-15 to get a more developed description of the whitelist contract entrypoints.
๐ Tests Cases
The smartContract tests are written in smartPy and in JS (with Taquito, Mocha and Chai)
To launch tests, you have to:
Originate the whitelist contract with:
yarn originate-whitelist
Paste the address of the originated whitelist SC in the conf file under /conf as following:
whitelistContractAddress: KT1-whitelist-address
Originate the euroTz contract with:
yarn originate-euroTz
Paste the address of the originated euroTz SC in the same conf file as follows:
Whitelist Smart Contract: SetAdmin Entrypoint testsinitialAdmin: tz1SVqTz7entj982jDSKcTQNgT7f2cg7C8dk------------------------------------------------------------MESSAGE STATEMENT: only admin may updateโ Update admin asnon-admin / Should fail (4409ms)OpHash : oo5ofnco8QxcMtjm4Xo3Px93knyssQBLhL2bCTeKHUSbpWW7fX3Admin from storage: tz1XrCvviH8CqoHMSKpKuznLArEa1yR9U7epโ Update admin asadmin / Shouldsucceed (27855ms)OpHash : oom91CsjUhFs9ThaSP2S2NgtYK4UT5HnceEHwr27i6bn3kvxeMXAdmin from storage: tz1SVqTz7entj982jDSKcTQNgT7f2cg7C8dkโ Reset old admin asadmin / Shouldsucceed (46817ms)3passing (1m)โจ Done in 82.75s.
yarn test-setIssuer # Test setIssuer entryPoint
Test Output:
Whitelist Smart Contract: SetIssuer Entrypoint testsinitialIssuer: tz1SVqTz7entj982jDSKcTQNgT7f2cg7C8dk------------------------------------------------------------MESSAGE STATEMENT: only admin may updateโ Update issuer asnon-admin / Should fail (5824ms)OpHash : ooERfBcJPaByiUdrhvidyHZEkZ2ki68LbVMz2mbPWrSJMfDwvzUIssuer from storage: tz1XrCvviH8CqoHMSKpKuznLArEa1yR9U7epโ Update issuer asadmin / Shouldsucceed (38408ms)OpHash : oooiEXQCbmtAFYZpqvDKbJzeyXvYGYqWatTfGxCYdxxZona1gZzIssuer from storage: tz1SVqTz7entj982jDSKcTQNgT7f2cg7C8dkโ Reset old issuer asadmin / Shouldsucceed (52151ms)3passing (2m)โจ Done in 101.61s.
yarn test-addUser # Test addUser entryPoint
Test Output:
Whitelist Smart Contract: AddUser Entrypoint testsMESSAGE STATEMENT: only admin may updateโ Add user asnon-admin / Should fail (2832ms)MESSAGE STATEMENT: issuer is not a userโ Add Issuer asastandarduserasadmin / Shouldfail (3734ms)OpHash : opVy3boRogtgpU2fz4wjgMwNEYxogymqGRqsUFzPdc7WChEzviqโ Add User with None asadmin / Shouldsucceed (16585ms)OpHash : ooZvAefYT4Q7bqi8K2AJQY1QWi3neMZVxEVqXGeAzsN52pHVKtzuserWhitelistID:10โ Add user with Some asadmin / Shouldsucceed (116256ms)4passing (2m)โจ Done in 142.39s.
yarn test-setWhitelistOutbound # Test setWhitelistOutbound entryPoint
Test Output:
Whitelist Smart Contract: SetWhitelistOutbound Entrypoint testsMESSAGE STATEMENT: only admin may updateโ Set Whitelist Outbound asnon-admin / Should fail (3120ms)OpHash: ooczsae6WA6xDTGYVhUuk4SS1WC55CFeqcBtPkdhGkVQjfqnrR6whitelistDetails: { allowed_whitelists: [], unrestricted:true }โ Set Whitelist Outbound asadminwithSome / Shouldsucceed (177318ms)OpHash: onjtUV2b4KWD67hNawDmKkndh1Hwa4JWDYmg83iXCrhn4ZDrGMBwhitelistDetails: {allowed_whitelists: [ 555 ], unrestricted:true}โ Update existing outbound whitelists asadmin / Shouldsucceed (36756ms)OpHash: oooTfhZYiiMQUjPpsTMXXdH6KUUQu6a5a4KDqV2k9BPaha798o6โ Remove outbound whitelist asadmin / Shouldsucceed (25887ms)4passing (4m)โจ Done in 247.35s.
Informative entrypoints
yarn test-viewEntryPoints # Test getters entryPoints
Test Output:
Whitelist Smart Contract: Informative Entrypoints testsviewOpHash : ooZZfDBazuXBiUsE2Vc3NAfg6f9eWPFdA6RooXqDtguajvpFGiYAdmin from view contract storage: tz1SVqTz7entj982jDSKcTQNgT7f2cg7C8dkโ Get Admin Address / Should succeed (84910ms)viewOpHash : oofULds4jJv6DyWw6v2nnh3FCogfgZhNvPwPTyica45zZzQAvzDIssuer from view contract storage: tz1SVqTz7entj982jDSKcTQNgT7f2cg7C8dkโ Get Issuer Address / Should succeed (16055ms)viewOpHash : op2rGJ3L2oczuUnkfshRetWgAkGSj2Zr6nahuGyzbAHfSJ3wNpwWhitelist details from view contract storage: { allowed_whitelists: [], unrestricted:true }โ Get WhitelistDetails / Should succeed (111324ms)viewOpHash : onq4VEiZ6q3SVKp8p1k7fya7auSL2m8WNaaUiphGi6XdJ2hv1NPwhiteListID from view contract storage:444โ Get User whitelist ID/ Should succeed (75185ms)MESSAGE STATEMENT: whitelist not foundโ Get inexistent WhitelistDetails / Should fail (2839ms)MESSAGE STATEMENT: user not foundโ Get inexistent User / Should fail (4059ms)6passing (5m)โจ Done in 302.18s.
Assertion entrypoints
yarn test-assertReceiver # Test assertReceiver entryPoint
Test Output:
Whitelist Smart Contract: AssertReceiver Entrypoint testsopHash : onsWLrfWngr7PGLjYTJWUE5Fn1N2pGcd8uWPXQb1b2G9TCRqLKnโ Assert receiver Issuer - Admin mints 50 euroTz to the Issuer / Should succeed (66577ms)MESSAGE STATEMENT: user not on a whitelistโ Assert receiver inexistent User - Admin tries to mint 40 euroTz to an inexistent user / Should fail (4432ms)OpHash : op5bsabpVa8FNszZJWmXi5TpDyYjz3AViovU1J3dMafo3Vha6m7โ Admin adds Ouss in users big_map (26387ms)MESSAGE STATEMENT: whitelist does not existโ Assert receiver existing User, his associated whitelistID don t refer to an existing whitelist - Admin tries to mint 40 euroTz / Should fail (5517ms)
OpHash : oodR5jieVi7enfGoVkUZcJdVnep5fyya7DFGQ576rJZzbtSEoAsโ Admin sets Ouss s whitelist outbound initally restricted (26856ms)MESSAGE STATEMENT: outbound restrictedโ Assert receiver existing User, his associated whitelist is restricted - Admin tries to mint 40 euroTz to whitelisted restricted user (Ouss) / Should fail (2814ms)
OpHash : oneyu5hcCPQopgvuQ2KsV4AjJLrNjkh2iKCWi96tuB9VceChcJXโ Admin sets Ouss s whitelist outbound unrestricted (106327ms)opHash : ooRxZ5HtiEfwtSrMpYgzJ6qWyt6qap87ThpRFP2mNpfjyughTH9โ Assert receiver existing User, the associated whitelistID refers to an existing whitelist and unrestricted - Admin mints 50 euroTz to Ouss: whitelisted unrestricted user / Should succeed (26285ms)
8passing (4m)โจ Done in 270.13s.
yarn test-assertReceivers # Test assertReceivers entryPoint
Test Output:
Whitelist Smart Contract: AssertReceivers Entrypoint testsMESSAGE STATEMENT: user not on a whitelistโ Assert receivers with one inexistent user / Should fail (3127ms)OpHash : ooHWW4VusZTuiDREUuXefX7rLbAQw1PZe38Vz8qJXJDdMTTeCDcโ Admin adds Khaled in whitelst contract (75338ms)MESSAGE STATEMENT: whitelist does not existโ Assert receivers with one user s whitelistID don t refer to an existing whitelist / Should fail (3524ms)OpHash: oo5W1bhrJmmSrv97mc5mS3Ee7Kqgbgu71vxJTYh1JW4jpM7QgZxโ Admin sets Khaled s whitelist outbound restricted (26590ms)MESSAGE STATEMENT: outbound restrictedโ Assert receivers with one user s whitelist restricted / Should fail (6387ms)OpHash : opZcnwmQvBPiHReqad11vSB3iFZbto4i5aBsUAH1Ck8k23gxCoQโ Admin sets Khaled s whitelist outbound unrestricted (55717ms)OpHash: opCXZZmrC4esizqy5trQgTPv3gKv4yE7SHmXMpXRzfgvWcgufV9โ Assert receivers: all users are existing and unrestricted / Sould succeed (35641ms)7passing (5m)โจ Done in 324.29s.
yarn test-assertTrasnfer # Test assertTrasnfer entryPoint
Test Output:
Whitelist Smart Contract: AssertTransfer Entrypoint testsMESSAGE STATEMENT: user not on a whitelistโ Assert Transfer from Issuer to an inexistent user - Issuer tries to transfer 9 euroTz to Fred / Should fail (3379ms)OpHash : oozZLubPscjt5ed9YaQi61Mfq94xNLAYC6bruTy3u2zHvcZSDcRโ Admin adds Fred in whitelst contract (91502ms)MESSAGE STATEMENT: whitelist does not existโ Assert Transfer from Issuer to an existing user with whitelistID don t refer to an existing whitelist - Issuer tries to transfer 9 euroTz to Fred / Should fail (5575ms)
OpHash: ooykfX3jCuioSabk69PV9BpLdxT5BCT7sbJMZB2sRH4sAogk6sWโ Admin sets Fred s whitelist outbound initally restricted (18412ms)MESSAGE STATEMENT: outbound restrictedโ Assert Transfer from Issuer to existing, restricted user - Issuer tries to transfer 9 euroTz to Fred / Should fail (7536ms)
OpHash: opMY1NtPZC9tmJAP2PCZqXQ6jfzKL6S5XDVvJpu6sYNjPHf8qvDโ Admin sets Fred s whitelist outbound unrestricted (36973ms)euroTzTrasnferOpHash: onxrnAwMs63ZvQKvG5T2GVhohfTuWdVcbKFLq9qQwzPgzTww5tSโ Assert Transfer from Issuer to an existing, unrestricted user - Issuer transfers 9 euroTz to Fred / Should succeed (27318ms)
MESSAGE STATEMENT: user not on a whitelistโ Assert Transfer from existing to an inexistent user - Fred tries to transfer 3 euroTz to Safwen / Should fail (4771ms)
OpHash : ooeXt7h7WrTsWNhFvwM4MJngD4pWb6eoCiLyDw3GmztBG1WkQU3โ Admin adds Safwen in whitelst contract (77621ms)MESSAGE STATEMENT: whitelist does not existโ Assert Transfer between: Two existing users with sender s whitelistID don t refer to an existing whitelist - Fred tries to transfer 3 euroTz to Safwen / Should fail (3318ms)
OpHash: op6oNdbhSAKixx795dQrogrDC9hzKYJissrJVBZbVeZ4Ldij8Kfโ Admin sets Safwen s whitelist outbound unrestricted (106412ms)OpHash: oobQx7dVeYVtTBs9WSSiBBD4onMQPcHcXwCSwc1nJgDqL7a9hU6โ Admin sets Fred s whitelist outbound restricted (61054ms)MESSAGE STATEMENT: outbound restrictedโ Assert Transfer between: Two existing users while sender is restricted - Fred tries to transfer 3 euroTz to Safwen / Should fail (3590ms)
OpHash : ooYvVeAkfasz18E7F935WYeG1B5Ur9RgjHWhJr4ohqtAoxPtDHDโ Admin sets Fred s whitelist outbound unrestricted and contains Safwen (31729ms)euroTzTrasnferOpHash : oorXEA6UpHcQhaFYp51sT11SYf6mpDMbvYDXKfwGawbUDEe5fKPโ Assert Transfer between: Two existing users, sender and receiver are unrestricted, receiver s whitelistID is in the sender s whitelist - Fred transfers 3 euroTz to Safwen / Should succeed (22084ms)
15passing (8m)โจ Done in 507.14s.
yarn test-assertTrasnfers # Test assertTrasnfers entryPoint
Test Output:
Whitelist Smart Contract: AssertTrasnfers Operation TestingMESSAGE STATEMENT: user not on a whitelistโ Assert list of transfers with one inexistent sender / Should fail (4333ms)MESSAGE STATEMENT: user not on a whitelistโ Assert list of transfers with one inexistent receiver / Should fail (2927ms)OpHash : opTmp7RmzQS3BypxzahgsjtzemypbLVXiepgsNGgXHqzJGLwecgโ Admin adds Daly to users big_map in whitelist contract (16347ms)MESSAGE STATEMENT: whitelist does not existโ Assert list of transfers with one sender s whitelistID don t refer to an existing whitelist / Should fail (3160ms)OpHash: oo9HkTbzfvffz8Zi6Avj4rAXqDysC4TtnpcDZt3zEde4vGKRQxUโ Admin sets Daly s whitelist outbound restricted (25520ms)MESSAGE STATEMENT: outbound restrictedโ Assert list of transfers with one restricted sender & restricted receiver / Should fail (2629ms)OpHash: op5s6LJTAPrBZ5FvDvNz5KC1V3mpHquef2N5BYP5deFhi5c6FLGโ Admin sets Daly s whitelist outbound unrestricted (74910ms)MESSAGE STATEMENT: outbound not whitelistedโ Assert list of transfers with one transfer where the receiver s whitelistID is not in the sender s whitelist / Should fail (2550ms)
OpHash: opEixE7d7tZF9XUcBP7ob6fSj91ifiYm4g4CBuFe43sszKK1TdPโ Admin adds Thib to Daly s whitelist (34924ms)OpHash: oo7ss2kbjivZvchJKRUWdyDGa5LTCJ6Ditb5jFUX6h7wj6pCWVSโ Assert list of transfers: all senders & receivers are existing and unrestricted, all receivers are whitelisted in the senders' whitelists / Should succeed (2662ms)
10passing (8m) โจ Done in 490.57s.
๐ฎ Roles:
Admin: the contract's owner and manager, he can:
โข Set a new contract's admin;
โข Set a new contract's issuer;
โข Add / Update / Delete any user in the users big_map;
โข Add / Update / Delete any whitelist in the whitelists big_map.
Issuer:
โข Can't be explicitly added to users;
โข Is always unrestricted;
โข Whose allowedWhitelists is the set of ALL whitelistId's
๐ Implementations
An implementation of wrapping and non-wrapping forms in Lorentz may be found here
A partial implementation of the compile-time wrapping form in LIGO may be found here