├── .gitignore ├── README.md ├── audits ├── certik │ └── audit.pdf └── hacken │ └── audit.pdf ├── build ├── Index.abi.json ├── Index.base64 ├── Index.code ├── Index.tvc ├── NativeVesting.abi.json ├── NativeVesting.base64 ├── NativeVesting.code ├── NativeVesting.tvc ├── TokenRootUpgradeable.abi.json ├── TokenRootUpgradeable.base64 ├── TokenRootUpgradeable.code ├── TokenRootUpgradeable.tvc ├── TokenWalletPlatform.abi.json ├── TokenWalletPlatform.base64 ├── TokenWalletPlatform.code ├── TokenWalletPlatform.tvc ├── TokenWalletUpgradeable.abi.json ├── TokenWalletUpgradeable.base64 ├── TokenWalletUpgradeable.code ├── TokenWalletUpgradeable.tvc ├── Vesting.abi.json ├── Vesting.base64 ├── Vesting.code ├── Vesting.tvc ├── VestingFactory.abi.json ├── VestingFactory.base64 ├── VestingFactory.code ├── VestingFactory.tvc ├── Wallet.abi.json ├── Wallet.base64 ├── Wallet.code ├── Wallet.tvc └── factorySource.ts ├── contracts ├── NativeVesting.sol ├── Vesting.sol ├── VestingFactory.sol ├── indexer │ ├── Index.tsol │ └── IndexFactory.tsol └── interfaces │ └── IFactory.sol ├── locklift.config.ts ├── package-lock.json ├── package.json ├── script ├── 1-deploy-factory.ts └── 2-indexing-example.ts ├── test ├── 1-main.ts ├── 2-native-main.ts ├── 3-indexer.ts ├── contracts │ ├── Wallet.sol │ └── build │ │ ├── Wallet.abi.json │ │ ├── Wallet.base64 │ │ ├── Wallet.code │ │ └── Wallet.tvc └── utils │ ├── common.ts │ ├── indexer.ts │ └── wrappers │ ├── token.ts │ └── token_wallet.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules 3 | 4 | script/reindex/data 5 | artifacts 6 | 7 | .DS_Store 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Venom linear vesting contract 2 | 3 | ## Table of Contents 4 | 5 | - [Venom linear vesting contract](#venom-linear-vesting-contract) 6 | - [Table of Contents](#table-of-contents) 7 | - [About](#about) 8 | - [Contracts](#contracts) 9 | - [VestingFactory](#vestingfactory) 10 | - [Vesting](#vesting) 11 | - [Call chain diagrams](#call-chain-diagrams) 12 | - [Vesting](#vesting-1) 13 | - [Native Vesting](#native-vesting) 14 | - [Getting Started](#getting-started) 15 | - [Commands](#commands) 16 | - [Test](#test) 17 | - [Deploy](#deploy) 18 | - [Compile](#compile) 19 | - [Verify](#verify) 20 | - [Audits](#audits) 21 | 22 | ## About 23 | 24 | ### Contracts 25 | 26 | #### VestingFactory 27 | 28 | Contract factory is responsible for deploying **Vesting** contracts. 29 | Could be used by anyone. Require `user`, `token`, `remainingGasTo`, `vesting amount`, `vesting start` and `vesting end` 30 | parameters for creating new instance of **Vesting** contract. 31 | Emits `NewVesting` event on new contract successful deploy. Creates indexes for each vesting contract. 32 | 33 | **VestingFactory** inherits from **IndexFactory** and deploys indexes to each Vesting contract. 34 | 35 | Indexes are used to look up contracts for a specific creator, recipient, and token by a hash code that can be obtained off-chain. See `./script/2-indexing-example.ts` for an example of how to use indexes. 36 | 37 | #### Vesting 38 | 39 | Contract, that is responsible for vesting `vesting amount` of specified `tokens` for certain `user`. 40 | Tokens are unlocked linearly every second from `vesting start` to `vesting end` and could be claimed at any time. 41 | Vesting contract should be deposited with `vesting amount` tokens by one transfer, otherwise, a deposit will be reverted 42 | and tokens will be sent back. Events are emitted on all actions including reverted deposit. 43 | 44 | 45 | ### Call chain diagrams 46 | 47 | #### Vesting 48 | 49 | ```mermaid 50 | sequenceDiagram 51 | title Vesting deployment call chain 52 | participant External 53 | participant Wallet 54 | participant VestingFactory 55 | participant Vesting 56 | participant TokenRoot 57 | participant VestingTokenWallet 58 | participant RecipientTokenWallet 59 | participant RecipientIndex 60 | participant CreatorIndex 61 | participant TokenIndex 62 | 63 | External->>Wallet: sendTransaction() 64 | Wallet->>VestingFactory: deployVesting(ARGS, VALUE, FLAG:0, BOUNCE: false) 65 | activate VestingFactory 66 | VestingFactory-->>VestingFactory: Validate ARGS & VALUE 67 | deactivate VestingFactory 68 | alt ARGS or VALUE is INVALID 69 | VestingFactory-->>Wallet: Revert transaction and return error code and all remaining value 70 | else ARGS & VALUE are VALID 71 | activate VestingFactory 72 | VestingFactory-->>VestingFactory: Reserve CONTRACT_MIN_BALANCE to avoid balance leakage 73 | VestingFactory->>Vesting: new Vesting(ARGS, VALUE, FLAG:128, BOUNCE: false)
// create new contract and send remaining value 74 | deactivate VestingFactory 75 | activate Vesting 76 | Vesting->>Vesting: Reserve CONTRACT_MIN_BALANCE 77 | Vesting->>TokenRoot: deployWallet(VALUE:TOKEN_WALLET_DEPLOY_VALUE, FLAG:128, BOUNCE: false)
// VestingTokenWallet 78 | TokenRoot->>VestingTokenWallet: onDeployRetry(VALUE, FLAG:128, BOUNCE: false) 79 | VestingTokenWallet->>VestingTokenWallet: reserve CONTRACT_MIN_BALANCE 80 | VestingTokenWallet->>Vesting: transfer(FLAG:128, BOUNCE: false)
// transfer remaining value 81 | TokenRoot->>RecipientTokenWallet: onDeployRetry(VALUE, FLAG:128, BOUNCE: false) 82 | RecipientTokenWallet->>RecipientTokenWallet: reserve CONTRACT_MIN_BALANCE 83 | RecipientTokenWallet->>Vesting: transfer(FLAG:128, BOUNCE: false)
// transfer remaining value 84 | Vesting->>TokenRoot: deployWallet(VALUE:TOKEN_WALLET_DEPLOY_VALUE, FLAG:128, BOUNCE: false)
// RecipientTokenWallet 85 | Vesting->>VestingFactory: onVestingDeployed(ARGS, VALUE, FLAG:128,BOUNCE: false) 86 | deactivate Vesting 87 | activate VestingFactory 88 | VestingFactory-->>VestingFactory: Reserve CONTRACT_MIN_BALANCE to avoid balance leakage 89 | VestingFactory->>RecipientIndex: deployUserIndex(VALUE:CONTRACT_MIN_BALANCE, FLAG:0, BOUNCE: false) 90 | VestingFactory->>CreatorIndex: deployUserIndex(VALUE:CONTRACT_MIN_BALANCE, FLAG:0, BOUNCE: false) 91 | VestingFactory->>TokenIndex: deployUserIndex(VALUE:CONTRACT_MIN_BALANCE, FLAG:0, BOUNCE: false) 92 | VestingFactory->>Wallet: transfer(FLAG:128, BOUNCE: false)
// transfer remaining value 93 | deactivate VestingFactory 94 | end 95 | ``` 96 | 97 | #### Native Vesting 98 | ```mermaid 99 | sequenceDiagram 100 | title Native Vesting deployment call chain 101 | participant External 102 | participant Wallet 103 | participant VestingFactory 104 | participant NativeVesting 105 | participant RecipientIndex 106 | participant CreatorIndex 107 | 108 | External->>Wallet: sendTransaction() 109 | Wallet->>VestingFactory: deployNativeVesting(ARGS, VALUE, FLAG:0, BOUNCE: false) 110 | activate VestingFactory 111 | VestingFactory-->>VestingFactory: Validate ARGS & VALUE 112 | deactivate VestingFactory 113 | alt ARGS or VALUE is INVALID 114 | VestingFactory-->>Wallet: Revert transaction and return error code and all remaining value 115 | else ARGS & VALUE are VALID 116 | activate VestingFactory 117 | VestingFactory-->>VestingFactory: Reserve CONTRACT_MIN_BALANCE to avoid balance leakage 118 | VestingFactory->>NativeVesting: new NativeVesting(ARGS, VALUE, FLAG:128, BOUNCE: false)
// create new contract and send remaining value 119 | deactivate VestingFactory 120 | activate NativeVesting 121 | NativeVesting->>NativeVesting: Reserve CONTRACT_MIN_BALANCE 122 | NativeVesting->>VestingFactory: onVestingDeployed(ARGS, VALUE, FLAG:128,BOUNCE: false) 123 | deactivate NativeVesting 124 | activate VestingFactory 125 | VestingFactory-->>VestingFactory: Reserve CONTRACT_MIN_BALANCE to avoid balance leakage 126 | VestingFactory->>RecipientIndex: deployUserIndex(VALUE:CONTRACT_MIN_BALANCE, FLAG:0, BOUNCE: false) 127 | VestingFactory->>CreatorIndex: deployUserIndex(VALUE:CONTRACT_MIN_BALANCE, FLAG:0, BOUNCE: false) 128 | VestingFactory->>Wallet: transfer(FLAG:128, BOUNCE: false)
// transfer remaining value 129 | deactivate VestingFactory 130 | end 131 | ``` 132 | 133 | 134 | 135 | ## Getting Started 136 | 137 | ### Commands 138 | 139 | #### Test 140 | 141 | ```bash 142 | npx locklift test --network local -t test --tests test/1-main.ts 143 | npx locklift test --network local -t test --tests test/2-native-main.ts 144 | npx locklift test --network local -t test --tests test/3-indexer.ts 145 | ``` 146 | 147 | #### Deploy 148 | 149 | ```bash 150 | # network - local|testnet|mainnet 151 | npx locklift run --network testnet --script script/1-deploy-factory.ts 152 | ``` 153 | 154 | #### Compile 155 | 156 | ```bash 157 | npx locklift build 158 | ``` 159 | 160 | #### Verify 161 | 162 | ```bash 163 | npx everscan-verify --api-url https://verify.venomscan.com verify -i ./ --license 'AGPL-3.0' --compiler-version bbbbeca6e6f22f9a2cd3f30021ca83aac1a1428d --linker-version 0.15.48 -I node_modules 164 | ``` 165 | 166 | ## Audits 167 | 168 | Security Assessment by [Certik](https://github.com/venom-blockchain/vesting/blob/main/audits/certik/audit.pdf) 169 | 170 | Security Assessment by [Hacken](https://github.com/venom-blockchain/vesting/blob/main/audits/hacken/audit.pdf) 171 | -------------------------------------------------------------------------------- /audits/certik/audit.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/venom-blockchain/vesting/47c022404231af7d4f309a3dc2c70ea5e9017501/audits/certik/audit.pdf -------------------------------------------------------------------------------- /audits/hacken/audit.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/venom-blockchain/vesting/47c022404231af7d4f309a3dc2c70ea5e9017501/audits/hacken/audit.pdf -------------------------------------------------------------------------------- /build/Index.abi.json: -------------------------------------------------------------------------------- 1 | { 2 | "ABI version": 2, 3 | "version": "2.2", 4 | "header": ["pubkey", "time", "expire"], 5 | "functions": [ 6 | { 7 | "name": "constructor", 8 | "inputs": [ 9 | ], 10 | "outputs": [ 11 | ] 12 | }, 13 | { 14 | "name": "getIndexedContract", 15 | "inputs": [ 16 | {"name":"answerId","type":"uint32"} 17 | ], 18 | "outputs": [ 19 | {"name":"value0","type":"address"} 20 | ] 21 | }, 22 | { 23 | "name": "getIndexFactory", 24 | "inputs": [ 25 | {"name":"answerId","type":"uint32"} 26 | ], 27 | "outputs": [ 28 | {"name":"value0","type":"address"} 29 | ] 30 | }, 31 | { 32 | "name": "getCodeHash", 33 | "inputs": [ 34 | {"name":"answerId","type":"uint32"} 35 | ], 36 | "outputs": [ 37 | {"name":"value0","type":"uint256"} 38 | ] 39 | }, 40 | { 41 | "name": "destruct", 42 | "inputs": [ 43 | {"name":"gasReceiver","type":"address"} 44 | ], 45 | "outputs": [ 46 | ] 47 | } 48 | ], 49 | "data": [ 50 | {"key":1,"name":"_indexedContract","type":"address"}, 51 | {"key":2,"name":"_saltHash","type":"uint256"} 52 | ], 53 | "events": [ 54 | ], 55 | "fields": [ 56 | {"name":"_pubkey","type":"uint256"}, 57 | {"name":"_timestamp","type":"uint64"}, 58 | {"name":"_constructorFlag","type":"bool"}, 59 | {"name":"_indexedContract","type":"address"}, 60 | {"name":"_saltHash","type":"uint256"}, 61 | {"name":"_indexFactory","type":"address"} 62 | ] 63 | } 64 | -------------------------------------------------------------------------------- /build/Index.base64: -------------------------------------------------------------------------------- 1 | te6ccgECIgEABIwAAgE0AwEBAcACAEPQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgBCSK7VMg4wMgwP/jAiDA/uMC8gsfBQQhA7ztRNDXScMB+GaJ+Gkh2zzTAAGOGYMI1xgg+QEB0wABlNP/AwGTAvhC4vkQ8qiV0wAB8nri0z8B+EMhufK0IPgjgQPoqIIIG3dAoLnytPhj0x8B+CO88rnTHwHbPPI8ExAGA3rtRNDXScMB+GYi0NMD+kAw+GmpOAD4RH9vcYIImJaAb3Jtb3Nwb3T4ZNwhxwDjAiHXDR/yvCHjAwHbPPI8Hh4GAiggghBotV8/u+MCIIIQbewkcrrjAgkHAtQw+Eby4EzTH/hEWG91+GTR2zwhjhoj0NMB+kAwMcjPhyDOghDt7CRyzwuBy//JcI4y+EQgbxMhbxL4SVUCbxHIz4SAygDPhEDOAfoC9ABxzwtpAcj4RG8Vzwsfy//NyfhEbxTi+wDjAPIACBcAJPhEcG9ycG9xgEBvdPhk+Cr5AAROIIILo63XuuMCIIIQCxCbwbrjAiCCEED6Z9q64wIgghBotV8/uuMCGRYUCgQ8MPhCbuMA+Ebyc9H4Kts8iCFus/Lr6SBu8n/Q+kAwEA0MCwIiiPhJIscF8uvq+AD4bNs88gAcGgA8U2FsdCBkb2Vzbid0IGNvbnRhaW4gYW55IHZhbHVlAhjQIIs4rbNYxwWKiuIODwEK103Q2zwPAELXTNCLL0pA1yb0BDHTCTGLL0oY1yYg10rCAZLXTZIwbeICFu1E0NdJwgGOgOMNER0CYnDtRND0BXEhgED0Do6A33IigED0Dm+Rk9cL/96J+Gz4a/hqgED0DvK91wv/+GJw+GMSEwECiRMAQ4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAD4jD4RvLgTPhCbuMA0x/4RFhvdfhk0ds8IY4dI9DTAfpAMDHIz4cgznHPC2EByM+TA+mfas7NyXCOMfhEIG8TIW8S+ElVAm8RyM+EgMoAz4RAzgH6AvQAcc8LaQHI+ERvFc8LH87NyfhEbxTi+wDjAPIAHRUXACD4RHBvcnBvcYBAb3T4ZPhMA+Iw+Eby4Ez4Qm7jANMf+ERYb3X4ZNHbPCGOHSPQ0wH6QDAxyM+HIM5xzwthAcjPkixCbwbOzclwjjH4RCBvEyFvEvhJVQJvEcjPhIDKAM+EQM4B+gL0AHHPC2kByPhEbxXPCx/Ozcn4RG8U4vsA4wDyAB0YFwAo7UTQ0//TPzH4Q1jIy//LP87J7VQAIPhEcG9ycG9xgEBvdPhk+EoDNjD4RvLgTPhCbuMAIZPU0dDe+kDR2zww2zzyAB0bGgA2+Ez4S/hK+EP4QsjL/8s/z4POWcjL/87Nye1UATKI+En4TMcF8uvqyM+FCM6Ab89AyYEAoPsAHAA4TWV0aG9kIGZvciBJbmRleEZhY3Rvcnkgb25seQA87UTQ0//TP9MAMfpA1NHQ0//6QNH4bPhr+Gr4Y/hiAAr4RvLgTAIK9KQg9KEhIAAUc29sIDAuNjIuMAAA -------------------------------------------------------------------------------- /build/Index.code: -------------------------------------------------------------------------------- 1 | .version sol 0.62.0 2 | 3 | .macro constructor 4 | DROP 5 | GETGLOB 2 6 | ISNULL 7 | IFREF { 8 | CALL $c4_to_c7_with_init_storage$ 9 | } 10 | GETGLOB 6 11 | THROWIF 51 12 | ENDS 13 | .loc ../contracts/indexer/Index.tsol, 22 14 | MYCODE 15 | 16 | CALLREF { 17 | CTOS 18 | PUSH S0 19 | PUSHSLICE x8adb35 20 | SDEQ 21 | PUSHREFCONT { 22 | PLDREFIDX 1 23 | CTOS 24 | CALLREF { 25 | 26 | PLDREF 27 | CTOS 28 | 29 | PUSHSLICE xF4A4_ 30 | SDBEGINSX 31 | 32 | LDDICT 33 | NIP 34 | 35 | LDU 10 36 | NIP 37 | 38 | PUSHSLICE xF4A1 39 | SDBEGINSX 40 | 41 | DUP 42 | SREFS 43 | GTINT 1 44 | PUSHCONT { 45 | PLDREFIDX 1 46 | } 47 | PUSHCONT { 48 | DROP 49 | NULL 50 | } 51 | IFELSE 52 | 53 | } 54 | } 55 | PUSHREFCONT { 56 | 57 | PLDREF 58 | CTOS 59 | 60 | PUSHSLICE xF4A4_ 61 | SDBEGINSX 62 | 63 | LDDICT 64 | NIP 65 | 66 | LDU 10 67 | NIP 68 | 69 | PUSHSLICE xF4A1 70 | SDBEGINSX 71 | 72 | DUP 73 | SREFS 74 | GTINT 1 75 | PUSHCONT { 76 | PLDREFIDX 1 77 | } 78 | PUSHCONT { 79 | DROP 80 | NULL 81 | } 82 | IFELSE 83 | 84 | } 85 | IFELSE 86 | } 87 | .loc ../contracts/indexer/Index.tsol, 23 88 | PUSHREF { 89 | .blob x53616c7420646f65736e277420636f6e7461696e20616e792076616c7565 90 | } 91 | OVER 92 | ISNULL 93 | NOT 94 | THROWARGIFNOT 1001 95 | .loc ../contracts/indexer/Index.tsol, 24 96 | DUP 97 | ISNULL 98 | THROWIF 63 99 | CTOS 100 | LDMSGADDR 101 | DROP 102 | .loc ../contracts/indexer/Index.tsol, 25 103 | PUSHREF { 104 | .blob x4d6574686f6420666f7220496e646578466163746f7279206f6e6c79 105 | } 106 | GETGLOB 9 107 | PUSH S2 108 | SDEQ 109 | THROWARGIFNOT 1002 110 | .loc ../contracts/indexer/Index.tsol, 26 111 | ACCEPT 112 | .loc ../contracts/indexer/Index.tsol, 27 113 | SETGLOB 12 114 | .loc ../contracts/indexer/Index.tsol, 0 115 | CALLREF { 116 | CALL $c7_to_c4$ 117 | } 118 | THROW 0 119 | 120 | .macro getIndexedContract 121 | DROP 122 | GETGLOB 6 123 | THROWIFNOT 76 124 | GETGLOB 2 125 | ISNULL 126 | IFREF { 127 | CALL $c4_to_c7$ 128 | } 129 | .loc ../contracts/indexer/Index.tsol, 34 130 | LDU 32 131 | GETGLOB 4 132 | ROT 133 | SETINDEXQ 5 134 | SETGLOB 4 135 | ENDS 136 | .loc ../contracts/indexer/Index.tsol, 0 137 | CALLREF { 138 | CALL $getIndexedContract_a1102985_internal_macro$ 139 | } 140 | OVER 141 | PUSHCONT { 142 | PUSH S3 143 | CTOS 144 | LDU 2 145 | LDMSGADDR 146 | DROP 147 | NIP 148 | NEWC 149 | STSLICECONST xc 150 | STSLICE 151 | PUSHINT 1 152 | STUR 98 153 | SWAP 154 | NEWC 155 | STSLICECONST x8b109bc1 156 | STSLICE 157 | STBREFR 158 | ENDC 159 | PUSHINT 0 160 | } 161 | PUSHCONT { 162 | GETGLOB 4 163 | DUP 164 | INDEX 3 165 | OVER 166 | THIRD 167 | GETGLOB 9 168 | ROLL 3 169 | SECOND 170 | NEWC 171 | STSLICECONST x2_ 172 | STI 1 173 | STSLICECONST x1_ 174 | STSLICE 175 | SWAP 176 | STGRAMS 177 | STDICT 178 | PUSHINT 1 179 | STUR 106 180 | SWAP 181 | NEWC 182 | GETGLOB 4 183 | INDEX 5 184 | STUR 32 185 | STSLICE 186 | STBREFR 187 | ENDC 188 | GETGLOB 4 189 | INDEX 4 190 | } 191 | IFELSE 192 | SENDRAWMSG 193 | IFREF { 194 | CALL $upd_only_time_in_c4$ 195 | } 196 | THROW 0 197 | 198 | .globl getIndexedContract_a1102985_internal 199 | .type getIndexedContract_a1102985_internal, @function 200 | CALL $getIndexedContract_a1102985_internal_macro$ 201 | 202 | .macro getIndexedContract_a1102985_internal_macro 203 | .loc ../contracts/indexer/Index.tsol, 35 204 | GETGLOB 4 205 | PUSHINT 0 206 | SETINDEXQ 2 207 | FALSE 208 | SETINDEXQ 1 209 | PUSHINT 64 210 | SETINDEXQ 4 211 | SETGLOB 4 212 | GETGLOB 10 213 | .loc ../contracts/indexer/Index.tsol, 0 214 | 215 | .macro getIndexFactory 216 | DROP 217 | GETGLOB 6 218 | THROWIFNOT 76 219 | GETGLOB 2 220 | ISNULL 221 | IFREF { 222 | CALL $c4_to_c7$ 223 | } 224 | .loc ../contracts/indexer/Index.tsol, 42 225 | LDU 32 226 | GETGLOB 4 227 | ROT 228 | SETINDEXQ 5 229 | SETGLOB 4 230 | ENDS 231 | .loc ../contracts/indexer/Index.tsol, 0 232 | CALLREF { 233 | CALL $getIndexFactory_d979c7d7_internal_macro$ 234 | } 235 | OVER 236 | PUSHCONT { 237 | PUSH S3 238 | CTOS 239 | LDU 2 240 | LDMSGADDR 241 | DROP 242 | NIP 243 | NEWC 244 | STSLICECONST xc 245 | STSLICE 246 | PUSHINT 1 247 | STUR 98 248 | SWAP 249 | NEWC 250 | STSLICECONST xc0fa67da 251 | STSLICE 252 | STBREFR 253 | ENDC 254 | PUSHINT 0 255 | } 256 | PUSHCONT { 257 | GETGLOB 4 258 | DUP 259 | INDEX 3 260 | OVER 261 | THIRD 262 | GETGLOB 9 263 | ROLL 3 264 | SECOND 265 | NEWC 266 | STSLICECONST x2_ 267 | STI 1 268 | STSLICECONST x1_ 269 | STSLICE 270 | SWAP 271 | STGRAMS 272 | STDICT 273 | PUSHINT 1 274 | STUR 106 275 | SWAP 276 | NEWC 277 | GETGLOB 4 278 | INDEX 5 279 | STUR 32 280 | STSLICE 281 | STBREFR 282 | ENDC 283 | GETGLOB 4 284 | INDEX 4 285 | } 286 | IFELSE 287 | SENDRAWMSG 288 | IFREF { 289 | CALL $upd_only_time_in_c4$ 290 | } 291 | THROW 0 292 | 293 | .globl getIndexFactory_d979c7d7_internal 294 | .type getIndexFactory_d979c7d7_internal, @function 295 | CALL $getIndexFactory_d979c7d7_internal_macro$ 296 | 297 | .macro getIndexFactory_d979c7d7_internal_macro 298 | .loc ../contracts/indexer/Index.tsol, 43 299 | GETGLOB 4 300 | PUSHINT 0 301 | SETINDEXQ 2 302 | FALSE 303 | SETINDEXQ 1 304 | PUSHINT 64 305 | SETINDEXQ 4 306 | SETGLOB 4 307 | GETGLOB 12 308 | .loc ../contracts/indexer/Index.tsol, 0 309 | 310 | .macro getCodeHash 311 | DROP 312 | GETGLOB 6 313 | THROWIFNOT 76 314 | .loc ../contracts/indexer/Index.tsol, 50 315 | LDU 32 316 | GETGLOB 4 317 | ROT 318 | SETINDEXQ 5 319 | SETGLOB 4 320 | ENDS 321 | .loc ../contracts/indexer/Index.tsol, 0 322 | CALLREF { 323 | CALL $getCodeHash_83dd41c6_internal_macro$ 324 | } 325 | OVER 326 | PUSHCONT { 327 | PUSH S3 328 | CTOS 329 | LDU 2 330 | LDMSGADDR 331 | DROP 332 | NIP 333 | NEWC 334 | STSLICECONST xc 335 | STSLICE 336 | PUSHINT 3991676018 337 | STUR 130 338 | STU 256 339 | ENDC 340 | PUSHINT 0 341 | } 342 | PUSHCONT { 343 | GETGLOB 4 344 | DUP 345 | INDEX 3 346 | OVER 347 | THIRD 348 | GETGLOB 9 349 | ROLL 3 350 | SECOND 351 | NEWC 352 | STSLICECONST x2_ 353 | STI 1 354 | STSLICECONST x1_ 355 | STSLICE 356 | SWAP 357 | STGRAMS 358 | STDICT 359 | PUSHINT 1 360 | STUR 106 361 | SWAP 362 | NEWC 363 | GETGLOB 4 364 | INDEX 5 365 | STUR 32 366 | STU 256 367 | STBREFR 368 | ENDC 369 | GETGLOB 4 370 | INDEX 4 371 | } 372 | IFELSE 373 | SENDRAWMSG 374 | IFREF { 375 | CALL $upd_only_time_in_c4$ 376 | } 377 | THROW 0 378 | 379 | .globl getCodeHash_83dd41c6_internal 380 | .type getCodeHash_83dd41c6_internal, @function 381 | CALL $getCodeHash_83dd41c6_internal_macro$ 382 | 383 | .macro getCodeHash_83dd41c6_internal_macro 384 | .loc ../contracts/indexer/Index.tsol, 51 385 | GETGLOB 4 386 | PUSHINT 0 387 | SETINDEXQ 2 388 | FALSE 389 | SETINDEXQ 1 390 | PUSHINT 64 391 | SETINDEXQ 4 392 | SETGLOB 4 393 | MYCODE 394 | HASHCU 395 | .loc ../contracts/indexer/Index.tsol, 0 396 | 397 | .macro destruct 398 | DROP 399 | GETGLOB 6 400 | THROWIFNOT 76 401 | GETGLOB 2 402 | ISNULL 403 | IFREF { 404 | CALL $c4_to_c7$ 405 | } 406 | .loc ../contracts/indexer/Index.tsol, 58 407 | OVER 408 | PUSHCONT { 409 | LDREF 410 | ENDS 411 | CTOS 412 | } 413 | IF 414 | LDMSGADDR 415 | ENDS 416 | .loc ../contracts/indexer/Index.tsol, 0 417 | CALLREF { 418 | CALL $destruct_1beb2615_internal_macro$ 419 | } 420 | DROP 421 | CALLREF { 422 | CALL $c7_to_c4$ 423 | } 424 | THROW 0 425 | 426 | .globl destruct_1beb2615_internal 427 | .type destruct_1beb2615_internal, @function 428 | CALL $destruct_1beb2615_internal_macro$ 429 | 430 | .macro destruct_1beb2615_internal_macro 431 | .loc ../contracts/indexer/Index.tsol, 59 432 | PUSHREF { 433 | .blob x4d6574686f6420666f7220496e646578466163746f7279206f6e6c79 434 | } 435 | GETGLOB 9 436 | GETGLOB 12 437 | SDEQ 438 | THROWARGIFNOT 1002 439 | .loc ../contracts/indexer/Index.tsol, 60 440 | NEWC 441 | STSLICECONST x42_ 442 | STSLICE 443 | PUSHINT 111 444 | STZEROES 445 | ENDC 446 | PUSHINT 160 447 | SENDRAWMSG 448 | .loc ../contracts/indexer/Index.tsol, 0 449 | 450 | .macro c4_to_c7 451 | PUSHROOT 452 | CTOS 453 | LDU 256 ; pubkey c4 454 | LDU 64 ; pubkey timestamp c4 455 | LDU 1 ; ctor flag 456 | NIP 457 | LDMSGADDR 458 | LDREF 459 | ENDS 460 | CTOS 461 | LDU 256 462 | LDMSGADDR 463 | ENDS 464 | SETGLOB 12 465 | SETGLOB 11 466 | SETGLOB 10 467 | SETGLOB 3 468 | SETGLOB 2 469 | 470 | .macro c4_to_c7_with_init_storage 471 | PUSHROOT 472 | CTOS 473 | SBITS 474 | GTINT 1 475 | PUSHCONT { 476 | PUSHINT 0 477 | PUSHROOT 478 | CTOS 479 | PLDDICT ; D 480 | PUSHINT 1 481 | OVER 482 | PUSHINT 64 483 | DICTUGET 484 | PUSHCONT { 485 | PUSHREFSLICE { 486 | .blob x8000000000000000000000000000000000000000000000000000000000000000001_ 487 | } 488 | } 489 | IFNOT 490 | PUSHINT 2 491 | PUSH S2 492 | PUSHINT 64 493 | DICTUGET 494 | ZEROSWAPIFNOT 495 | PUSHCONT { 496 | PLDU 256 497 | } 498 | IF 499 | PUSHREFSLICE { 500 | .blob x8000000000000000000000000000000000000000000000000000000000000000001_ 501 | } 502 | SETGLOB 12 503 | SETGLOB 11 504 | SETGLOB 10 505 | PUSHINT 64 506 | DICTUGET 507 | THROWIFNOT 61 508 | PLDU 256 509 | SETGLOB 2 510 | PUSHINT 0 ; timestamp 511 | SETGLOB 3 512 | } 513 | IFREFELSE { 514 | CALL $c4_to_c7$ 515 | } 516 | 517 | .macro c7_to_c4 518 | GETGLOB 12 519 | GETGLOB 11 520 | GETGLOB 10 521 | GETGLOB 3 522 | GETGLOB 2 523 | NEWC 524 | STU 256 525 | STU 64 526 | STONE 527 | STSLICE 528 | ROTREV 529 | NEWC 530 | STU 256 531 | STSLICE 532 | STBREFR 533 | ENDC 534 | POPROOT 535 | 536 | .macro upd_only_time_in_c4 537 | PUSHROOT 538 | CTOS 539 | LDU 256 540 | LDU 64 541 | NIP 542 | GETGLOB 3 543 | ROT 544 | NEWC 545 | STU 256 546 | STU 64 547 | STSLICE 548 | ENDC 549 | POPROOT 550 | 551 | .internal-alias :main_internal, 0 552 | .internal :main_internal 553 | PUSHROOT 554 | CTOS 555 | SBITS 556 | NEQINT 1 557 | SETGLOB 6 558 | PUSH S2 559 | CTOS 560 | LDU 4 ; bounced tail 561 | LDMSGADDR ; bounced src tail 562 | DROP 563 | SETGLOB 9 564 | MODPOW2 1 565 | GETGLOB 4 566 | TRUE 567 | SETINDEXQ 1 568 | PUSHINT 10000000 569 | SETINDEXQ 2 570 | NULL 571 | SETINDEXQ 3 572 | PUSHINT 0 573 | SETINDEXQ 4 574 | SETGLOB 4 575 | IFRET 576 | OVER 577 | SEMPTY ; isEmpty 578 | IFJMPREF { 579 | GETGLOB 6 580 | THROWIFNOT 76 581 | } 582 | OVER 583 | LDUQ 32 ; [funcId] body' ok 584 | THROWIFNOT 60 585 | OVER 586 | IFNOTJMPREF { 587 | GETGLOB 6 588 | THROWIFNOT 76 589 | } 590 | SWAP 591 | CALLREF { 592 | CALL $public_function_selector$ 593 | } 594 | THROW 60 595 | 596 | .internal-alias :main_external, -1 597 | .internal :main_external 598 | PUSHROOT 599 | CTOS 600 | SBITS 601 | NEQINT 1 602 | SETGLOB 6 603 | PUSHREFSLICE { 604 | .blob x8000000000000000000000000000000000000000000000000000000000000000001_ 605 | } 606 | SETGLOB 9 607 | OVER 608 | CALLREF { 609 | CALL $c4_to_c7_with_init_storage$ 610 | } 611 | LDU 1 ; haveSign msgSlice 612 | SWAP 613 | PUSHCONT { 614 | PUSHPOW2 9 615 | LDSLICEX ; signatureSlice msgSlice 616 | DUP 617 | HASHSU ; signatureSlice msgSlice hashMsgSlice 618 | SWAP 619 | LDU 1 ; signatureSlice hashMsgSlice hasPubkey msgSlice 620 | SWAP 621 | PUSHCONT { 622 | LDU 256 ; signatureSlice hashMsgSlice pubkey msgSlice 623 | XCHG S3 624 | SWAP 625 | } 626 | PUSHCONT { 627 | XCHG S2 628 | GETGLOB 2 629 | } 630 | IFELSE 631 | CHKSIGNU ; msgSlice isSigned 632 | THROWIFNOT 40 633 | } 634 | PUSHCONT { 635 | LDU 1 ; hasPubkey msgSlice 636 | SWAP 637 | THROWIF 58 638 | } 639 | IFELSE 640 | LDU 64 ; timestamp msgSlice 641 | SWAP 642 | CALL $replay_protection_macro$ 643 | LDU 32 ; expireAt msgSlice 644 | SWAP 645 | NOW ; msgSlice expireAt now 646 | GREATER ; msgSlice expireAt>now 647 | THROWIFNOT 57 648 | LDU 32 ; funcId body 649 | SWAP 650 | CALLREF { 651 | CALL $public_function_selector$ 652 | } 653 | THROW 60 654 | 655 | .macro public_function_selector 656 | DUP 657 | PUSHINT 1756716863 658 | LEQ 659 | IFJMPREF { 660 | DUP 661 | PUSHINT 61058519 662 | EQUAL 663 | IFJMPREF { 664 | CALL $destruct$ 665 | } 666 | DUP 667 | PUSHINT 185637825 668 | EQUAL 669 | IFJMPREF { 670 | CALL $getIndexedContract$ 671 | } 672 | DUP 673 | PUSHINT 1090152410 674 | EQUAL 675 | IFJMPREF { 676 | CALL $getIndexFactory$ 677 | } 678 | DUP 679 | PUSHINT 1756716863 680 | EQUAL 681 | IFJMPREF { 682 | CALL $constructor$ 683 | } 684 | } 685 | DUP 686 | PUSHINT 1844192370 687 | EQUAL 688 | IFJMPREF { 689 | CALL $getCodeHash$ 690 | } 691 | 692 | -------------------------------------------------------------------------------- /build/Index.tvc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/venom-blockchain/vesting/47c022404231af7d4f309a3dc2c70ea5e9017501/build/Index.tvc -------------------------------------------------------------------------------- /build/NativeVesting.abi.json: -------------------------------------------------------------------------------- 1 | { 2 | "ABI version": 2, 3 | "version": "2.2", 4 | "header": ["time", "expire"], 5 | "functions": [ 6 | { 7 | "name": "constructor", 8 | "inputs": [ 9 | {"name":"_user","type":"address"}, 10 | {"name":"_creator","type":"address"}, 11 | {"name":"_remainingGasTo","type":"address"}, 12 | {"name":"_vestingAmount","type":"uint128"}, 13 | {"name":"_vestingStart","type":"uint32"}, 14 | {"name":"_vestingEnd","type":"uint32"} 15 | ], 16 | "outputs": [ 17 | ] 18 | }, 19 | { 20 | "name": "getDetails", 21 | "inputs": [ 22 | ], 23 | "outputs": [ 24 | {"name":"_user","type":"address"}, 25 | {"name":"_creator","type":"address"}, 26 | {"name":"_vestingAmount","type":"uint128"}, 27 | {"name":"_vestingStart","type":"uint32"}, 28 | {"name":"_vestingEnd","type":"uint32"}, 29 | {"name":"_lastClaimTime","type":"uint32"}, 30 | {"name":"_balance","type":"uint128"}, 31 | {"name":"_filled","type":"bool"}, 32 | {"name":"_vested","type":"bool"}, 33 | {"name":"_nonce","type":"uint128"}, 34 | {"name":"_factory","type":"address"} 35 | ] 36 | }, 37 | { 38 | "name": "deposit", 39 | "inputs": [ 40 | {"name":"send_gas_to","type":"address"} 41 | ], 42 | "outputs": [ 43 | ] 44 | }, 45 | { 46 | "name": "pendingVested", 47 | "inputs": [ 48 | ], 49 | "outputs": [ 50 | {"name":"value_to_claim","type":"uint128"} 51 | ] 52 | }, 53 | { 54 | "name": "claim", 55 | "inputs": [ 56 | ], 57 | "outputs": [ 58 | ] 59 | } 60 | ], 61 | "data": [ 62 | {"key":1,"name":"nonce","type":"uint128"}, 63 | {"key":2,"name":"factory","type":"address"} 64 | ], 65 | "events": [ 66 | { 67 | "name": "Deposit", 68 | "inputs": [ 69 | {"name":"sender","type":"address"}, 70 | {"name":"amount","type":"uint128"} 71 | ], 72 | "outputs": [ 73 | ] 74 | }, 75 | { 76 | "name": "Claim", 77 | "inputs": [ 78 | {"name":"amount","type":"uint128"}, 79 | {"name":"remaining_amount","type":"uint128"} 80 | ], 81 | "outputs": [ 82 | ] 83 | }, 84 | { 85 | "name": "Vested", 86 | "inputs": [ 87 | ], 88 | "outputs": [ 89 | ] 90 | } 91 | ], 92 | "fields": [ 93 | {"name":"_pubkey","type":"uint256"}, 94 | {"name":"_timestamp","type":"uint64"}, 95 | {"name":"_constructorFlag","type":"bool"}, 96 | {"name":"nonce","type":"uint128"}, 97 | {"name":"factory","type":"address"}, 98 | {"name":"user","type":"address"}, 99 | {"name":"creator","type":"address"}, 100 | {"name":"vestingAmount","type":"uint128"}, 101 | {"name":"vestingStart","type":"uint32"}, 102 | {"name":"vestingEnd","type":"uint32"}, 103 | {"name":"lastClaimTime","type":"uint32"}, 104 | {"name":"balance","type":"uint128"}, 105 | {"name":"filled","type":"bool"}, 106 | {"name":"vested","type":"bool"} 107 | ] 108 | } 109 | -------------------------------------------------------------------------------- /build/NativeVesting.base64: -------------------------------------------------------------------------------- 1 | te6ccgECIAEABREAAgE0AwEBAcACAEPQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgBCSK7VMg4wMgwP/jAiDA/uMC8gsdBQQfA5jtRNDXScMB+GaJ+Gkh2zzTAAGegwjXGCD5AVj4QvkQ8qje0z8B+EMhufK0IPgjgQPoqIIIG3dAoLnytPhj0x8B+CO88rnTHwHbPPI8GxcGA1LtRNDXScMB+GYi0NMD+kAw+GmpOADcIccA4wIh1w0f8rwh4wMB2zzyPBwcBgIoIIIQWoWz4LvjAiCCEH+duES64wIJBwNoMPhG8uBM+EJu4wDR2zwhjhwj0NMB+kAwMcjPhyDOghD/nbhEzwuBy3/JcPsAkTDi4wDyABgICwBYcPgj+FC+kzD4Uo4f+CP4Ub6OF/hQ+FGhtR/4I/hRobUf+FKotX8BqQQx3uIEUCCCEA1NXjK64wIgghAPcw8wuuMCIIIQQsUwcLrjAiCCEFqFs+C64wIUEg0KA6Qw+Eby4Ez4Qm7jANHbPCuOOS3Q0wH6QDAxyM+HIM5xzwthXqDIz5NqFs+CzlWQyM7Lf8sfyx/LH8t/ygDKAFnIy3/Ozc3NyXD7AJJfC+LjAPIAGAwLACjtRNDT/9M/MfhDWMjL/8s/zsntVAAs+Ez4TfhO+E/4UPhR+FL4U/hU+Er4SwMmMPhG8uBM+EJu4wDR2zww2zzyABgOFgH8+En4TMcF8uPp+CP4T77y4+z4U3+68uPt+FRwuvLj7mim/mCCEDuaygC+8uPvcPgj+FC+kzD4Uo4X+FD4UaG1H/gj+FGhtR/4Uqi1fwGpBDHi+FIhobV/+HL4I/hx+FIBjQRwAAAAAAAAAAAAAAAAHQ+G76DIzst/y3/JcPsADwFG+FKOgN/4UoIQO5rKAKC1f3D7AvhJyM+FCM6Ab89AyYMG+wAQAQ5/+HSIcPsAEQAiwAAAAAAAAAAAAAAAAGxzTBsDNjD4RvLgTPhCbuMAIZPU0dDe+kDR2zww2zzyABgTFgC8aKb+YPhOghA7msoAoLV/vvLj7/hTcLry4+v4Tvhyf/hz+E74SY0EcAAAAAAAAAAAAAAAABX8gLZgyM7Oy3/JcPsA+E6CEDuaygCgtX9w+wLIz4UIzoBvz0DJgwb7AAL8MPhCbuMA+EbycyGT1NHQ3vpA1NHQ+kDU0dD6QNN/0x/TH9H4SfhLxwXy4+qCEDuaygBw+wJVBPhsVQP4bVj4bgH4b/hw+E/4cfhQ+E/4TosCVQP4TfhM+Er4S8jPhYjOcc8LblVwyM+QxCWOTst/zlVQyM5VQMjOVTDIzst/FxUBIssfyx/Nzc3NyYMG+wDbPPIAFgCG+FT4U/hS+FH4UPhP+E74TfhM+Ev4SvhD+ELIy//LP8+Dy39VkMjOVYDIzlVwyM7Lf8sfyx/LH8t/ygDKAM3NzcntVAIW7UTQ10nCAY6A4w0ZGACI7UTQ0//TP9MAMdN/1NHQ+kDU0dD6QNTR0PpA03/TH9Mf0x/Tf9IA0gDR+HT4c/hy+HH4cPhv+G74bfhs+Gv4avhj+GICinDtRND0BXEhgED0Dm+Rk9cLf95yIoBA9A6OgN+JIHBfYPh0+HP4cvhx+HD4b/hu+G34bPhr+GqAQPQO8r3XC//4YnD4YxobAQKJGwBDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAK+Eby4EwCCvSkIPShHx4AFHNvbCAwLjYyLjAAAA== -------------------------------------------------------------------------------- /build/NativeVesting.code: -------------------------------------------------------------------------------- 1 | .version sol 0.62.0 2 | 3 | .macro constructor 4 | DROP 5 | GETGLOB 2 6 | ISNULL 7 | IFREF { 8 | CALL $c4_to_c7_with_init_storage$ 9 | } 10 | GETGLOB 6 11 | THROWIF 51 12 | OVER 13 | PUSHCONT { 14 | LDREF 15 | ENDS 16 | CTOS 17 | } 18 | IF 19 | LDMSGADDR 20 | LDREF 21 | ENDS 22 | CTOS 23 | LDMSGADDR 24 | LDREF 25 | ENDS 26 | CTOS 27 | LDMSGADDR 28 | LDU 128 29 | LDU 32 30 | LDU 32 31 | ENDS 32 | .loc ../contracts/NativeVesting.sol, 46 33 | GETGLOB 9 34 | GETGLOB 11 35 | SDEQ 36 | THROWIFNOT 1002 37 | .loc ../contracts/NativeVesting.sol, 47 38 | PUSHINT 1000000000 39 | PUSHINT 0 40 | RAWRESERVE 41 | .loc ../contracts/NativeVesting.sol, 49 42 | ROLL 5 43 | SETGLOB 12 44 | .loc ../contracts/NativeVesting.sol, 50 45 | ROLL 4 46 | SETGLOB 13 47 | .loc ../contracts/NativeVesting.sol, 51 48 | ROT 49 | SETGLOB 14 50 | .loc ../contracts/NativeVesting.sol, 52 51 | SWAP 52 | SETGLOB 15 53 | .loc ../contracts/NativeVesting.sol, 53 54 | SETGLOB 16 55 | .loc ../contracts/NativeVesting.sol, 54 56 | GETGLOB 15 57 | SETGLOB 17 58 | .loc ../contracts/NativeVesting.sol, 56 59 | GETGLOB 16 60 | GETGLOB 15 61 | GETGLOB 14 62 | PUSHSLICE x2_ 63 | ROLL 4 64 | GETGLOB 13 65 | GETGLOB 12 66 | GETGLOB 10 67 | GETGLOB 11 68 | NEWC 69 | STSLICECONST x62_ 70 | STSLICE 71 | PUSHINT 1 72 | STUR 111 73 | ROLLREV 8 74 | NEWC 75 | STSLICECONST x31096393 76 | STU 128 77 | STSLICE 78 | ROLLREV 6 79 | NEWC 80 | STSLICE 81 | ROLLREV 5 82 | NEWC 83 | STSLICE 84 | ROLLREV 4 85 | NEWC 86 | STSLICE 87 | STU 128 88 | STU 32 89 | STU 32 90 | STBREFR 91 | STBREFR 92 | STBREFR 93 | STBREFR 94 | ENDC 95 | PUSHPOW2 7 96 | SENDRAWMSG 97 | .loc ../contracts/NativeVesting.sol, 0 98 | CALLREF { 99 | CALL $c7_to_c4$ 100 | } 101 | THROW 0 102 | 103 | .macro getDetails 104 | DROP 105 | GETGLOB 6 106 | THROWIFNOT 76 107 | GETGLOB 2 108 | ISNULL 109 | IFREF { 110 | CALL $c4_to_c7$ 111 | } 112 | .loc ../contracts/NativeVesting.sol, 71 113 | ENDS 114 | .loc ../contracts/NativeVesting.sol, 0 115 | CALLREF { 116 | CALL $getDetails_fbbf93a0_internal_macro$ 117 | } 118 | PUSH S11 119 | PUSHCONT { 120 | PUSH S13 121 | CTOS 122 | LDU 2 123 | LDMSGADDR 124 | DROP 125 | NIP 126 | NEWC 127 | STSLICECONST xc 128 | STSLICE 129 | PUSHINT 1 130 | STUR 98 131 | REVERSE 12, 0 132 | NEWC 133 | STSLICECONST xda85b3e0 134 | STSLICE 135 | ROLLREV 10 136 | NEWC 137 | STSLICE 138 | STU 128 139 | STU 32 140 | STU 32 141 | STU 32 142 | STU 128 143 | STI 1 144 | STI 1 145 | ROTREV 146 | NEWC 147 | STU 128 148 | STSLICE 149 | STBREFR 150 | STBREFR 151 | STBREFR 152 | ENDC 153 | PUSHINT 0 154 | SENDRAWMSG 155 | } 156 | PUSHCONT { 157 | BLKDROP 11 158 | } 159 | IFELSE 160 | IFREF { 161 | CALL $upd_only_time_in_c4$ 162 | } 163 | THROW 0 164 | 165 | .macro getDetails_fbbf93a0_internal_macro 166 | .loc ../contracts/NativeVesting.sol, 88 167 | GETGLOB 12 168 | GETGLOB 13 169 | GETGLOB 14 170 | GETGLOB 15 171 | GETGLOB 16 172 | GETGLOB 17 173 | GETGLOB 18 174 | GETGLOB 19 175 | GETGLOB 20 176 | GETGLOB 10 177 | GETGLOB 11 178 | .loc ../contracts/NativeVesting.sol, 0 179 | 180 | .macro deposit 181 | DROP 182 | GETGLOB 6 183 | THROWIFNOT 76 184 | GETGLOB 2 185 | ISNULL 186 | IFREF { 187 | CALL $c4_to_c7$ 188 | } 189 | .loc ../contracts/NativeVesting.sol, 103 190 | OVER 191 | PUSHCONT { 192 | LDREF 193 | ENDS 194 | CTOS 195 | } 196 | IF 197 | LDMSGADDR 198 | ENDS 199 | .loc ../contracts/NativeVesting.sol, 0 200 | CALLREF { 201 | CALL $deposit_f340fa01_internal_macro$ 202 | } 203 | DROP 204 | CALLREF { 205 | CALL $c7_to_c4$ 206 | } 207 | THROW 0 208 | 209 | .macro deposit_f340fa01_internal_macro 210 | .loc ../contracts/NativeVesting.sol, 104 211 | DEPTH 212 | ADDCONST -2 213 | PICK 214 | GETGLOB 14 215 | PUSHINT 1000000000 216 | ADD 217 | UFITS 128 218 | GEQ 219 | THROWIFNOT 1007 220 | .loc ../contracts/NativeVesting.sol, 105 221 | GETGLOB 19 222 | FALSE 223 | EQUAL 224 | THROWIFNOT 1003 225 | .loc ../contracts/NativeVesting.sol, 107 226 | GETGLOB 14 227 | SETGLOB 18 228 | .loc ../contracts/NativeVesting.sol, 108 229 | TRUE 230 | SETGLOB 19 231 | .loc ../contracts/NativeVesting.sol, 110 232 | GETGLOB 14 233 | GETGLOB 9 234 | PUSHSLICE xc000000000000000000000000057f202d9 235 | NEWC 236 | STSLICE 237 | STSLICE 238 | STU 128 239 | ENDC 240 | PUSHINT 0 241 | SENDRAWMSG 242 | .loc ../contracts/NativeVesting.sol, 111 243 | GETGLOB 14 244 | PUSHINT 1000000000 245 | ADD 246 | UFITS 128 247 | PUSHINT 0 248 | RAWRESERVE 249 | .loc ../contracts/NativeVesting.sol, 113 250 | NEWC 251 | STSLICECONST x42_ 252 | STSLICE 253 | PUSHINT 111 254 | STZEROES 255 | ENDC 256 | PUSHPOW2 7 257 | SENDRAWMSG 258 | .loc ../contracts/NativeVesting.sol, 0 259 | 260 | .macro pendingVested 261 | DROP 262 | GETGLOB 6 263 | THROWIFNOT 76 264 | GETGLOB 2 265 | ISNULL 266 | IFREF { 267 | CALL $c4_to_c7$ 268 | } 269 | .loc ../contracts/NativeVesting.sol, 116 270 | ENDS 271 | .loc ../contracts/NativeVesting.sol, 0 272 | CALLREF { 273 | CALL $pendingVested_214493a6_internal_macro$ 274 | } 275 | OVER 276 | PUSHCONT { 277 | PUSH S3 278 | CTOS 279 | LDU 2 280 | LDMSGADDR 281 | DROP 282 | NIP 283 | NEWC 284 | STSLICECONST xc 285 | STSLICE 286 | PUSHINT 4288526404 287 | STUR 130 288 | STU 128 289 | ENDC 290 | PUSHINT 0 291 | SENDRAWMSG 292 | } 293 | PUSHCONT { 294 | DROP 295 | } 296 | IFELSE 297 | IFREF { 298 | CALL $upd_only_time_in_c4$ 299 | } 300 | THROW 0 301 | 302 | .macro pendingVested_214493a6_internal_macro 303 | .loc ../contracts/NativeVesting.sol, 116 304 | PUSHINT 0 305 | .loc ../contracts/NativeVesting.sol, 117 306 | NOW 307 | GETGLOB 16 308 | GEQ 309 | PUSHCONT { 310 | .loc ../contracts/NativeVesting.sol, 118 311 | DROP 312 | GETGLOB 18 313 | } 314 | PUSHCONT { 315 | NOW 316 | GETGLOB 17 317 | GEQ 318 | PUSHCONT { 319 | .loc ../contracts/NativeVesting.sol, 120 320 | GETGLOB 16 321 | GETGLOB 17 322 | SUB 323 | UFITS 32 324 | .loc ../contracts/NativeVesting.sol, 121 325 | NOW 326 | GETGLOB 17 327 | SUB 328 | UFITS 32 329 | .loc ../contracts/NativeVesting.sol, 122 330 | GETGLOB 18 331 | MUL 332 | UFITS 128 333 | SWAP 334 | DIV 335 | NIP 336 | .loc ../contracts/NativeVesting.sol, 0 337 | } 338 | IF 339 | } 340 | IFELSE 341 | .loc ../contracts/NativeVesting.sol, 0 342 | 343 | .macro claim 344 | DROP 345 | GETGLOB 6 346 | THROWIFNOT 76 347 | GETGLOB 2 348 | ISNULL 349 | IFREF { 350 | CALL $c4_to_c7$ 351 | } 352 | .loc ../contracts/NativeVesting.sol, 126 353 | ENDS 354 | .loc ../contracts/NativeVesting.sol, 0 355 | CALLREF { 356 | CALL $claim_4e71d92d_internal_macro$ 357 | } 358 | DROP 359 | CALLREF { 360 | CALL $c7_to_c4$ 361 | } 362 | THROW 0 363 | 364 | .macro claim_4e71d92d_internal_macro 365 | .loc ../contracts/NativeVesting.sol, 127 366 | GETGLOB 9 367 | GETGLOB 12 368 | SDEQ 369 | THROWIFNOT 1001 370 | .loc ../contracts/NativeVesting.sol, 128 371 | NOW 372 | GETGLOB 15 373 | GEQ 374 | THROWIFNOT 1004 375 | .loc ../contracts/NativeVesting.sol, 129 376 | GETGLOB 19 377 | TRUE 378 | EQUAL 379 | THROWIFNOT 1005 380 | .loc ../contracts/NativeVesting.sol, 130 381 | GETGLOB 20 382 | FALSE 383 | EQUAL 384 | THROWIFNOT 1006 385 | .loc ../contracts/NativeVesting.sol, 131 386 | DEPTH 387 | ADDCONST -2 388 | PICK 389 | PUSHINT 1000000000 390 | GEQ 391 | THROWIFNOT 1007 392 | .loc ../contracts/NativeVesting.sol, 133 393 | PUSHINT 0 394 | .loc ../contracts/NativeVesting.sol, 134 395 | NOW 396 | GETGLOB 16 397 | GEQ 398 | PUSHCONT { 399 | .loc ../contracts/NativeVesting.sol, 135 400 | DROP 401 | GETGLOB 18 402 | } 403 | PUSHCONT { 404 | .loc ../contracts/NativeVesting.sol, 137 405 | GETGLOB 16 406 | GETGLOB 17 407 | SUB 408 | UFITS 32 409 | .loc ../contracts/NativeVesting.sol, 138 410 | NOW 411 | GETGLOB 17 412 | SUB 413 | UFITS 32 414 | .loc ../contracts/NativeVesting.sol, 139 415 | GETGLOB 18 416 | MUL 417 | UFITS 128 418 | SWAP 419 | DIV 420 | NIP 421 | } 422 | IFELSE 423 | .loc ../contracts/NativeVesting.sol, 142 424 | GETGLOB 18 425 | OVER 426 | SUB 427 | UFITS 128 428 | SETGLOB 18 429 | .loc ../contracts/NativeVesting.sol, 143 430 | NOW 431 | SETGLOB 17 432 | .loc ../contracts/NativeVesting.sol, 145 433 | GETGLOB 18 434 | SWAP 435 | PUSHSLICE xc0000000000000000000000000743e1bbe 436 | NEWC 437 | STSLICE 438 | STU 128 439 | STU 128 440 | ENDC 441 | PUSHINT 0 442 | SENDRAWMSG 443 | .loc ../contracts/NativeVesting.sol, 146 444 | GETGLOB 18 445 | PUSHCONT { 446 | .loc ../contracts/NativeVesting.sol, 147 447 | TRUE 448 | SETGLOB 20 449 | .loc ../contracts/NativeVesting.sol, 148 450 | PUSHREF { 451 | .blob xc00000000000000000000000006c734c1b 452 | } 453 | PUSHINT 0 454 | SENDRAWMSG 455 | .loc ../contracts/NativeVesting.sol, 0 456 | } 457 | IFNOT 458 | .loc ../contracts/NativeVesting.sol, 151 459 | GETGLOB 18 460 | PUSHINT 1000000000 461 | ADD 462 | UFITS 128 463 | PUSHINT 0 464 | RAWRESERVE 465 | .loc ../contracts/NativeVesting.sol, 152 466 | GETGLOB 9 467 | NEWC 468 | STSLICECONST x42_ 469 | STSLICE 470 | PUSHINT 111 471 | STZEROES 472 | ENDC 473 | PUSHPOW2 7 474 | SENDRAWMSG 475 | .loc ../contracts/NativeVesting.sol, 0 476 | 477 | .macro c4_to_c7 478 | PUSHROOT 479 | CTOS 480 | LDU 256 ; pubkey c4 481 | LDU 64 ; pubkey timestamp c4 482 | LDU 1 ; ctor flag 483 | NIP 484 | LDU 128 485 | LDREF 486 | ENDS 487 | CTOS 488 | LDMSGADDR 489 | LDREF 490 | ENDS 491 | CTOS 492 | LDMSGADDR 493 | LDREF 494 | ENDS 495 | CTOS 496 | LDMSGADDR 497 | LDU 128 498 | LDU 32 499 | LDU 32 500 | LDU 32 501 | LDU 128 502 | LDI 1 503 | LDI 1 504 | ENDS 505 | SETGLOB 20 506 | SETGLOB 19 507 | SETGLOB 18 508 | SETGLOB 17 509 | SETGLOB 16 510 | SETGLOB 15 511 | SETGLOB 14 512 | SETGLOB 13 513 | SETGLOB 12 514 | SETGLOB 11 515 | SETGLOB 10 516 | SETGLOB 3 517 | SETGLOB 2 518 | 519 | .macro c4_to_c7_with_init_storage 520 | PUSHROOT 521 | CTOS 522 | SBITS 523 | GTINT 1 524 | PUSHCONT { 525 | PUSHINT 0 526 | PUSHROOT 527 | CTOS 528 | PLDDICT ; D 529 | PUSHINT 1 530 | OVER 531 | PUSHINT 64 532 | DICTUGET 533 | ZEROSWAPIFNOT 534 | PUSHCONT { 535 | PLDU 128 536 | } 537 | IF 538 | PUSHINT 2 539 | PUSH S2 540 | PUSHINT 64 541 | DICTUGET 542 | PUSHCONT { 543 | PUSHREFSLICE { 544 | .blob x8000000000000000000000000000000000000000000000000000000000000000001_ 545 | } 546 | } 547 | IFNOT 548 | PUSHREFSLICE { 549 | .blob x8000000000000000000000000000000000000000000000000000000000000000001_ 550 | } 551 | DUP 552 | PUSHINT 0 553 | BLKPUSH 6, 0 554 | SETGLOB 20 555 | SETGLOB 19 556 | SETGLOB 18 557 | SETGLOB 17 558 | SETGLOB 16 559 | SETGLOB 15 560 | SETGLOB 14 561 | SETGLOB 13 562 | SETGLOB 12 563 | SETGLOB 11 564 | SETGLOB 10 565 | PUSHINT 64 566 | DICTUGET 567 | THROWIFNOT 61 568 | PLDU 256 569 | SETGLOB 2 570 | PUSHINT 0 ; timestamp 571 | SETGLOB 3 572 | } 573 | IFREFELSE { 574 | CALL $c4_to_c7$ 575 | } 576 | 577 | .macro c7_to_c4 578 | GETGLOB 20 579 | GETGLOB 19 580 | GETGLOB 18 581 | GETGLOB 17 582 | GETGLOB 16 583 | GETGLOB 15 584 | GETGLOB 14 585 | GETGLOB 13 586 | GETGLOB 12 587 | GETGLOB 11 588 | GETGLOB 10 589 | GETGLOB 3 590 | GETGLOB 2 591 | NEWC 592 | STU 256 593 | STU 64 594 | STONE 595 | STU 128 596 | ROLLREV 10 597 | NEWC 598 | STSLICE 599 | ROLLREV 9 600 | NEWC 601 | STSLICE 602 | ROLLREV 8 603 | NEWC 604 | STSLICE 605 | STU 128 606 | STU 32 607 | STU 32 608 | STU 32 609 | STU 128 610 | STI 1 611 | STI 1 612 | STBREFR 613 | STBREFR 614 | STBREFR 615 | ENDC 616 | POPROOT 617 | 618 | .macro upd_only_time_in_c4 619 | PUSHROOT 620 | CTOS 621 | LDU 256 622 | LDU 64 623 | NIP 624 | GETGLOB 3 625 | ROT 626 | NEWC 627 | STU 256 628 | STU 64 629 | STSLICE 630 | ENDC 631 | POPROOT 632 | 633 | .internal-alias :main_internal, 0 634 | .internal :main_internal 635 | PUSHROOT 636 | CTOS 637 | SBITS 638 | NEQINT 1 639 | SETGLOB 6 640 | PUSH S2 641 | CTOS 642 | LDU 4 ; bounced tail 643 | LDMSGADDR ; bounced src tail 644 | DROP 645 | SETGLOB 9 646 | MODPOW2 1 647 | IFRET 648 | OVER 649 | SEMPTY ; isEmpty 650 | IFJMPREF { 651 | GETGLOB 6 652 | THROWIFNOT 76 653 | } 654 | OVER 655 | LDUQ 32 ; [funcId] body' ok 656 | THROWIFNOT 60 657 | OVER 658 | IFNOTJMPREF { 659 | GETGLOB 6 660 | THROWIFNOT 76 661 | } 662 | SWAP 663 | CALLREF { 664 | CALL $public_function_selector$ 665 | } 666 | THROW 60 667 | 668 | .internal-alias :main_external, -1 669 | .internal :main_external 670 | PUSHROOT 671 | CTOS 672 | SBITS 673 | NEQINT 1 674 | SETGLOB 6 675 | PUSHREFSLICE { 676 | .blob x8000000000000000000000000000000000000000000000000000000000000000001_ 677 | } 678 | SETGLOB 9 679 | OVER 680 | CALLREF { 681 | CALL $c4_to_c7_with_init_storage$ 682 | } 683 | LDU 1 ; haveSign msgSlice 684 | SWAP 685 | PUSHCONT { 686 | PUSHPOW2 9 687 | LDSLICEX ; signatureSlice msgSlice 688 | DUP 689 | HASHSU ; signatureSlice msgSlice hashMsgSlice 690 | ROT 691 | GETGLOB 2 692 | CHKSIGNU ; msgSlice isSigned 693 | THROWIFNOT 40 694 | } 695 | IF 696 | LDU 64 ; timestamp msgSlice 697 | SWAP 698 | CALL $replay_protection_macro$ 699 | LDU 32 ; expireAt msgSlice 700 | SWAP 701 | NOW ; msgSlice expireAt now 702 | GREATER ; msgSlice expireAt>now 703 | THROWIFNOT 57 704 | LDU 32 ; funcId body 705 | SWAP 706 | CALLREF { 707 | CALL $public_function_selector$ 708 | } 709 | THROW 60 710 | 711 | .macro public_function_selector 712 | DUP 713 | PUSHINT 1518711776 714 | LEQ 715 | IFJMPREF { 716 | DUP 717 | PUSHINT 223174194 718 | EQUAL 719 | IFJMPREF { 720 | CALL $constructor$ 721 | } 722 | DUP 723 | PUSHINT 259198768 724 | EQUAL 725 | IFJMPREF { 726 | CALL $deposit$ 727 | } 728 | DUP 729 | PUSHINT 1120219248 730 | EQUAL 731 | IFJMPREF { 732 | CALL $claim$ 733 | } 734 | DUP 735 | PUSHINT 1518711776 736 | EQUAL 737 | IFJMPREF { 738 | CALL $getDetails$ 739 | } 740 | } 741 | DUP 742 | PUSHINT 2141042756 743 | EQUAL 744 | IFJMPREF { 745 | CALL $pendingVested$ 746 | } 747 | 748 | -------------------------------------------------------------------------------- /build/NativeVesting.tvc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/venom-blockchain/vesting/47c022404231af7d4f309a3dc2c70ea5e9017501/build/NativeVesting.tvc -------------------------------------------------------------------------------- /build/TokenRootUpgradeable.abi.json: -------------------------------------------------------------------------------- 1 | { 2 | "ABI version": 2, 3 | "version": "2.2", 4 | "header": ["pubkey", "time", "expire"], 5 | "functions": [ 6 | { 7 | "name": "constructor", 8 | "inputs": [ 9 | {"name":"initialSupplyTo","type":"address"}, 10 | {"name":"initialSupply","type":"uint128"}, 11 | {"name":"deployWalletValue","type":"uint128"}, 12 | {"name":"mintDisabled","type":"bool"}, 13 | {"name":"burnByRootDisabled","type":"bool"}, 14 | {"name":"burnPaused","type":"bool"}, 15 | {"name":"remainingGasTo","type":"address"} 16 | ], 17 | "outputs": [ 18 | ] 19 | }, 20 | { 21 | "name": "supportsInterface", 22 | "inputs": [ 23 | {"name":"answerId","type":"uint32"}, 24 | {"name":"interfaceID","type":"uint32"} 25 | ], 26 | "outputs": [ 27 | {"name":"value0","type":"bool"} 28 | ] 29 | }, 30 | { 31 | "name": "walletVersion", 32 | "inputs": [ 33 | {"name":"answerId","type":"uint32"} 34 | ], 35 | "outputs": [ 36 | {"name":"value0","type":"uint32"} 37 | ] 38 | }, 39 | { 40 | "name": "platformCode", 41 | "inputs": [ 42 | {"name":"answerId","type":"uint32"} 43 | ], 44 | "outputs": [ 45 | {"name":"value0","type":"cell"} 46 | ] 47 | }, 48 | { 49 | "name": "requestUpgradeWallet", 50 | "inputs": [ 51 | {"name":"currentVersion","type":"uint32"}, 52 | {"name":"walletOwner","type":"address"}, 53 | {"name":"remainingGasTo","type":"address"} 54 | ], 55 | "outputs": [ 56 | ] 57 | }, 58 | { 59 | "name": "setWalletCode", 60 | "inputs": [ 61 | {"name":"code","type":"cell"} 62 | ], 63 | "outputs": [ 64 | ] 65 | }, 66 | { 67 | "name": "upgrade", 68 | "inputs": [ 69 | {"name":"code","type":"cell"} 70 | ], 71 | "outputs": [ 72 | ] 73 | }, 74 | { 75 | "name": "disableMint", 76 | "inputs": [ 77 | {"name":"answerId","type":"uint32"} 78 | ], 79 | "outputs": [ 80 | {"name":"value0","type":"bool"} 81 | ] 82 | }, 83 | { 84 | "name": "mintDisabled", 85 | "inputs": [ 86 | {"name":"answerId","type":"uint32"} 87 | ], 88 | "outputs": [ 89 | {"name":"value0","type":"bool"} 90 | ] 91 | }, 92 | { 93 | "name": "burnTokens", 94 | "inputs": [ 95 | {"name":"amount","type":"uint128"}, 96 | {"name":"walletOwner","type":"address"}, 97 | {"name":"remainingGasTo","type":"address"}, 98 | {"name":"callbackTo","type":"address"}, 99 | {"name":"payload","type":"cell"} 100 | ], 101 | "outputs": [ 102 | ] 103 | }, 104 | { 105 | "name": "disableBurnByRoot", 106 | "inputs": [ 107 | {"name":"answerId","type":"uint32"} 108 | ], 109 | "outputs": [ 110 | {"name":"value0","type":"bool"} 111 | ] 112 | }, 113 | { 114 | "name": "burnByRootDisabled", 115 | "inputs": [ 116 | {"name":"answerId","type":"uint32"} 117 | ], 118 | "outputs": [ 119 | {"name":"value0","type":"bool"} 120 | ] 121 | }, 122 | { 123 | "name": "burnPaused", 124 | "inputs": [ 125 | {"name":"answerId","type":"uint32"} 126 | ], 127 | "outputs": [ 128 | {"name":"value0","type":"bool"} 129 | ] 130 | }, 131 | { 132 | "name": "setBurnPaused", 133 | "inputs": [ 134 | {"name":"answerId","type":"uint32"}, 135 | {"name":"paused","type":"bool"} 136 | ], 137 | "outputs": [ 138 | {"name":"value0","type":"bool"} 139 | ] 140 | }, 141 | { 142 | "name": "transferOwnership", 143 | "inputs": [ 144 | {"name":"newOwner","type":"address"}, 145 | {"name":"remainingGasTo","type":"address"}, 146 | {"components":[{"name":"value","type":"uint128"},{"name":"payload","type":"cell"}],"name":"callbacks","type":"map(address,tuple)"} 147 | ], 148 | "outputs": [ 149 | ] 150 | }, 151 | { 152 | "name": "name", 153 | "inputs": [ 154 | {"name":"answerId","type":"uint32"} 155 | ], 156 | "outputs": [ 157 | {"name":"value0","type":"string"} 158 | ] 159 | }, 160 | { 161 | "name": "symbol", 162 | "inputs": [ 163 | {"name":"answerId","type":"uint32"} 164 | ], 165 | "outputs": [ 166 | {"name":"value0","type":"string"} 167 | ] 168 | }, 169 | { 170 | "name": "decimals", 171 | "inputs": [ 172 | {"name":"answerId","type":"uint32"} 173 | ], 174 | "outputs": [ 175 | {"name":"value0","type":"uint8"} 176 | ] 177 | }, 178 | { 179 | "name": "totalSupply", 180 | "inputs": [ 181 | {"name":"answerId","type":"uint32"} 182 | ], 183 | "outputs": [ 184 | {"name":"value0","type":"uint128"} 185 | ] 186 | }, 187 | { 188 | "name": "walletCode", 189 | "inputs": [ 190 | {"name":"answerId","type":"uint32"} 191 | ], 192 | "outputs": [ 193 | {"name":"value0","type":"cell"} 194 | ] 195 | }, 196 | { 197 | "name": "rootOwner", 198 | "inputs": [ 199 | {"name":"answerId","type":"uint32"} 200 | ], 201 | "outputs": [ 202 | {"name":"value0","type":"address"} 203 | ] 204 | }, 205 | { 206 | "name": "walletOf", 207 | "inputs": [ 208 | {"name":"answerId","type":"uint32"}, 209 | {"name":"walletOwner","type":"address"} 210 | ], 211 | "outputs": [ 212 | {"name":"value0","type":"address"} 213 | ] 214 | }, 215 | { 216 | "name": "deployWallet", 217 | "inputs": [ 218 | {"name":"answerId","type":"uint32"}, 219 | {"name":"walletOwner","type":"address"}, 220 | {"name":"deployWalletValue","type":"uint128"} 221 | ], 222 | "outputs": [ 223 | {"name":"tokenWallet","type":"address"} 224 | ] 225 | }, 226 | { 227 | "name": "mint", 228 | "inputs": [ 229 | {"name":"amount","type":"uint128"}, 230 | {"name":"recipient","type":"address"}, 231 | {"name":"deployWalletValue","type":"uint128"}, 232 | {"name":"remainingGasTo","type":"address"}, 233 | {"name":"notify","type":"bool"}, 234 | {"name":"payload","type":"cell"} 235 | ], 236 | "outputs": [ 237 | ] 238 | }, 239 | { 240 | "name": "acceptBurn", 241 | "id": "0x192B51B1", 242 | "inputs": [ 243 | {"name":"amount","type":"uint128"}, 244 | {"name":"walletOwner","type":"address"}, 245 | {"name":"remainingGasTo","type":"address"}, 246 | {"name":"callbackTo","type":"address"}, 247 | {"name":"payload","type":"cell"} 248 | ], 249 | "outputs": [ 250 | ] 251 | }, 252 | { 253 | "name": "sendSurplusGas", 254 | "inputs": [ 255 | {"name":"to","type":"address"} 256 | ], 257 | "outputs": [ 258 | ] 259 | } 260 | ], 261 | "data": [ 262 | {"key":1,"name":"name_","type":"string"}, 263 | {"key":2,"name":"symbol_","type":"string"}, 264 | {"key":3,"name":"decimals_","type":"uint8"}, 265 | {"key":4,"name":"rootOwner_","type":"address"}, 266 | {"key":5,"name":"walletCode_","type":"cell"}, 267 | {"key":6,"name":"randomNonce_","type":"uint256"}, 268 | {"key":7,"name":"deployer_","type":"address"}, 269 | {"key":8,"name":"platformCode_","type":"cell"} 270 | ], 271 | "events": [ 272 | ], 273 | "fields": [ 274 | {"name":"_pubkey","type":"uint256"}, 275 | {"name":"_timestamp","type":"uint64"}, 276 | {"name":"_constructorFlag","type":"bool"}, 277 | {"name":"name_","type":"string"}, 278 | {"name":"symbol_","type":"string"}, 279 | {"name":"decimals_","type":"uint8"}, 280 | {"name":"rootOwner_","type":"address"}, 281 | {"name":"walletCode_","type":"cell"}, 282 | {"name":"totalSupply_","type":"uint128"}, 283 | {"name":"burnPaused_","type":"bool"}, 284 | {"name":"burnByRootDisabled_","type":"bool"}, 285 | {"name":"mintDisabled_","type":"bool"}, 286 | {"name":"randomNonce_","type":"uint256"}, 287 | {"name":"deployer_","type":"address"}, 288 | {"name":"platformCode_","type":"cell"}, 289 | {"name":"walletVersion_","type":"uint32"} 290 | ] 291 | } 292 | -------------------------------------------------------------------------------- /build/TokenRootUpgradeable.base64: -------------------------------------------------------------------------------- 1 | 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 95 | zMsfzcntVA== 96 | -------------------------------------------------------------------------------- /build/TokenRootUpgradeable.tvc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/venom-blockchain/vesting/47c022404231af7d4f309a3dc2c70ea5e9017501/build/TokenRootUpgradeable.tvc -------------------------------------------------------------------------------- /build/TokenWalletPlatform.abi.json: -------------------------------------------------------------------------------- 1 | { 2 | "ABI version": 2, 3 | "version": "2.2", 4 | "header": ["time"], 5 | "functions": [ 6 | { 7 | "name": "constructor", 8 | "id": "0x15A038FB", 9 | "inputs": [ 10 | {"name":"walletCode","type":"cell"}, 11 | {"name":"walletVersion","type":"uint32"}, 12 | {"name":"sender","type":"address"}, 13 | {"name":"remainingGasTo","type":"address"} 14 | ], 15 | "outputs": [ 16 | ] 17 | } 18 | ], 19 | "data": [ 20 | {"key":1,"name":"root","type":"address"}, 21 | {"key":2,"name":"owner","type":"address"} 22 | ], 23 | "events": [ 24 | ], 25 | "fields": [ 26 | {"name":"_pubkey","type":"uint256"}, 27 | {"name":"_timestamp","type":"uint64"}, 28 | {"name":"_constructorFlag","type":"bool"}, 29 | {"name":"root","type":"address"}, 30 | {"name":"owner","type":"address"} 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /build/TokenWalletPlatform.base64: -------------------------------------------------------------------------------- 1 | te6ccgECGwEAApkAAgE0AwEBAcACAEPQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAg 2 | AgaK2zUaBAQkiu1TIOMDIMD/4wIgwP7jAvILFgcGBQAAA4rtRNDXScMB+GaJ+Gkh2zzTAAGfgQIA 3 | 1xgg+QFY+EL5EPKo3tM/AfhDIbnytCD4I4ED6KiCCBt3QKC58rT4Y9MfAds88jwUEAgDUu1E0NdJ 4 | wwH4ZiLQ0wP6QDD4aak4ANwhxwDjAiHXDR/yvCHjAwHbPPI8FRUIARQgghAVoDj7uuMCCQSQMPhC 5 | buMA+EbycyGW1NMf1NHQk9TTH+L6QNTR0PpA0fhJ+ErHBSCOgN+OgI4UIMjPhQjOgG/PQMmBAICm 6 | ILUH+wDiXwTbPPIAEA0KGQEIXSLbPAsCfPhKyM74SwHOcAHLf3AByx8Syx/O+EGIyM+OK2zWzM7J 7 | Acwh+wQB0CCLOK2zWMcFk9dN0N7XTNDtHu1Tyds8GgwABPACAR4wIfpCbxPXC//DACCOgN4OARAw 8 | Ids8+EnHBQ8BfnDIy/9wbYBA9EP4SnFYgED0FgFyWIBA9BbI9ADJ+EGIyM+OK2zWzM7JyM+EgPQA 9 | 9ADPgcn5AMjPigBAy//J0BoCFu1E0NdJwgGOgOMNEhEANO1E0NP/0z/TADH6QNTR0PpA0fhr+Gr4 10 | Y/hiAlRw7UTQ9AVxIYBA9A6OgN9yIoBA9A6OgN/4a/hqgED0DvK91wv/+GJw+GMTEwECiRQAQ4AA 11 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAACvhG8uBMAgr0pCD0oRgXABRzb2wgMC41 12 | Ny4xARigAAAAAjDbPPgP8gAZACz4SvhD+ELIy//LP8+DzvhLyM7Nye1UAAwg+GHtHtk= 13 | -------------------------------------------------------------------------------- /build/TokenWalletPlatform.code: -------------------------------------------------------------------------------- 1 | .version sol 0.57.1 2 | 3 | .pragma selector-save-my-code 4 | 5 | .macro constructor 6 | DROP 7 | GETGLOB 2 8 | ISNULL 9 | IFREF { 10 | CALL $c4_to_c7_with_init_storage$ 11 | } 12 | GETGLOB 6 13 | THROWIF 51 14 | OVER 15 | PUSHCONT { 16 | LDREF 17 | LDU 32 18 | LDREF 19 | ENDS 20 | CTOS 21 | } 22 | PUSHCONT { 23 | LDREF 24 | LDU 32 25 | } 26 | IFELSE 27 | LDMSGADDR 28 | LDREF 29 | ENDS 30 | CTOS 31 | LDMSGADDR 32 | ENDS 33 | .loc ../contracts/TokenWalletPlatform.sol, 13 34 | GETGLOB 9 35 | GETGLOB 10 36 | SDEQ 37 | DUP 38 | PUSHCONT { 39 | DROP 40 | OVER 41 | PARSEMSGADDR 42 | INDEX 3 43 | PLDU 256 44 | NEQINT 0 45 | DUP 46 | PUSHCONT { 47 | DROP 48 | OVER 49 | CALLREF { 50 | CALL $_getExpectedAddress_internal_macro$ 51 | } 52 | GETGLOB 9 53 | SDEQ 54 | } 55 | IF 56 | } 57 | IFNOT 58 | PUSHCONT { 59 | .loc ../contracts/TokenWalletPlatform.sol, 14 60 | OVER2 61 | PUSH S2 62 | CALLREF { 63 | CALL $initialize_internal_macro$ 64 | } 65 | } 66 | PUSHCONT { 67 | .loc ../contracts/TokenWalletPlatform.sol, 16 68 | DUP 69 | NEWC 70 | STSLICECONST x42_ 71 | STSLICE 72 | PUSHINT 111 73 | STZEROES 74 | ENDC 75 | PUSHINT 128 76 | ADDCONST 32 77 | UFITS 8 78 | SENDRAWMSG 79 | } 80 | IFELSE 81 | .loc ../contracts/TokenWalletPlatform.sol, 0 82 | BLKDROP 4 83 | CALLREF { 84 | CALL $c7_to_c4$ 85 | } 86 | THROW 0 87 | 88 | .globl _getExpectedAddress_internal 89 | .type _getExpectedAddress_internal, @function 90 | CALL $_getExpectedAddress_internal_macro$ 91 | 92 | .macro _getExpectedAddress_internal_macro 93 | .loc ../contracts/TokenWalletPlatform.sol, 25 94 | PUSHINT 0 95 | NEWC 96 | STU 256 97 | PUSHINT 0 98 | NEWDICT 99 | PUSHINT 64 100 | DICTUSETB 101 | GETGLOB 10 102 | PUSHINT 1 103 | ROT 104 | PUSHINT 64 105 | DICTUSET 106 | SWAP 107 | PUSHINT 2 108 | ROT 109 | PUSHINT 64 110 | DICTUSET 111 | NEWC 112 | STDICT 113 | ENDC 114 | GETGLOB 1 115 | PUSHREF { 116 | DUP 117 | SETGLOB 1 118 | BLESS 119 | JMPX 120 | } 121 | NEWC 122 | STSLICECONST x8adb35 123 | STREF 124 | STSLICE 125 | ENDC 126 | NEWC 127 | STSLICECONST x2_ 128 | STOPTREF 129 | STOPTREF 130 | STZERO 131 | ENDC 132 | .loc ../contracts/TokenWalletPlatform.sol, 35 133 | HASHCU 134 | NEWC 135 | STSLICECONST x801_ 136 | STU 256 137 | ENDC 138 | CTOS 139 | .loc ../contracts/TokenWalletPlatform.sol, 0 140 | 141 | .globl initialize_internal 142 | .type initialize_internal, @function 143 | CALL $initialize_internal_macro$ 144 | 145 | .macro initialize_internal_macro 146 | .loc ../contracts/TokenWalletPlatform.sol, 41 147 | GETGLOB 10 148 | NEWC 149 | STSLICE 150 | .loc ../contracts/TokenWalletPlatform.sol, 42 151 | GETGLOB 11 152 | SWAP 153 | STSLICE 154 | .loc ../contracts/TokenWalletPlatform.sol, 43 155 | PUSHINT 0 156 | SWAP 157 | STU 128 158 | .loc ../contracts/TokenWalletPlatform.sol, 44 159 | PUSHINT 0 160 | SWAP 161 | STU 32 162 | .loc ../contracts/TokenWalletPlatform.sol, 45 163 | XCHG S1, S2 164 | STU 32 165 | .loc ../contracts/TokenWalletPlatform.sol, 46 166 | STSLICE 167 | .loc ../contracts/TokenWalletPlatform.sol, 48 168 | GETGLOB 1 169 | PUSHREF { 170 | DUP 171 | SETGLOB 1 172 | BLESS 173 | JMPX 174 | } 175 | NEWC 176 | STSLICECONST x8adb35 177 | STREF 178 | STSLICE 179 | ENDC 180 | SWAP 181 | STREF 182 | .loc ../contracts/TokenWalletPlatform.sol, 50 183 | OVER 184 | SETCODE 185 | .loc ../contracts/TokenWalletPlatform.sol, 51 186 | SWAP 187 | CTOS 188 | DUP 189 | PUSHSLICE x8adb35 190 | SDEQ 191 | PUSHCONT { 192 | PLDREFIDX 1 193 | CTOS 194 | } 195 | IF 196 | PLDREF 197 | CTOS 198 | BLESS 199 | POP C3 200 | .loc ../contracts/TokenWalletPlatform.sol, 53 201 | ENDC 202 | CALLREF { 203 | CALL $:onCodeUpgrade$ 204 | } 205 | .loc ../contracts/TokenWalletPlatform.sol, 0 206 | 207 | .internal-alias :onCodeUpgrade, 2 208 | .internal :onCodeUpgrade 209 | DROP 210 | .loc ../contracts/TokenWalletPlatform.sol, 0 211 | CALLREF { 212 | CALL $c7_to_c4$ 213 | } 214 | COMMIT 215 | THROW 0 216 | 217 | .macro c4_to_c7 218 | PUSHROOT 219 | CTOS 220 | LDU 256 ; pubkey c4 221 | LDU 64 ; pubkey timestamp c4 222 | LDU 1 ; ctor flag 223 | NIP 224 | LDMSGADDR 225 | LDREF 226 | ENDS 227 | CTOS 228 | LDMSGADDR 229 | ENDS 230 | SETGLOB 11 231 | SETGLOB 10 232 | SETGLOB 3 233 | SETGLOB 2 234 | 235 | .macro c4_to_c7_with_init_storage 236 | PUSHROOT 237 | CTOS 238 | SBITS 239 | GTINT 1 240 | PUSHCONT { 241 | PUSHINT 0 242 | PUSHROOT 243 | CTOS 244 | PLDDICT ; D 245 | PUSHINT 1 246 | OVER 247 | PUSHINT 64 248 | DICTUGET 249 | PUSHCONT { 250 | PUSHREFSLICE { 251 | .blob x8000000000000000000000000000000000000000000000000000000000000000001_ 252 | } 253 | } 254 | IFNOT 255 | PUSHINT 2 256 | PUSH S2 257 | PUSHINT 64 258 | DICTUGET 259 | PUSHCONT { 260 | PUSHREFSLICE { 261 | .blob x8000000000000000000000000000000000000000000000000000000000000000001_ 262 | } 263 | } 264 | IFNOT 265 | SETGLOB 11 266 | SETGLOB 10 267 | PUSHINT 64 268 | DICTUGET 269 | THROWIFNOT 61 270 | PLDU 256 271 | SETGLOB 2 272 | PUSHINT 0 ; timestamp 273 | SETGLOB 3 274 | } 275 | IFREFELSE { 276 | CALL $c4_to_c7$ 277 | } 278 | 279 | .macro c7_to_c4 280 | GETGLOB 10 281 | GETGLOB 3 282 | GETGLOB 2 283 | NEWC 284 | STU 256 285 | STU 64 286 | STONE 287 | STSLICE 288 | GETGLOB 11 289 | NEWC 290 | STSLICE 291 | STBREFR 292 | ENDC 293 | POPROOT 294 | 295 | .macro upd_only_time_in_c4 296 | PUSHROOT 297 | CTOS 298 | LDU 256 299 | LDU 64 300 | NIP 301 | GETGLOB 3 302 | ROT 303 | NEWC 304 | STU 256 305 | STU 64 306 | STSLICE 307 | ENDC 308 | POPROOT 309 | 310 | .internal-alias :main_internal, 0 311 | .internal :main_internal 312 | PUSHROOT 313 | CTOS 314 | SBITS 315 | NEQINT 1 316 | SETGLOB 6 317 | PUSH S2 318 | CTOS 319 | LDU 4 ; bounced tail 320 | LDMSGADDR ; bounced src tail 321 | DROP 322 | SETGLOB 9 323 | MODPOW2 1 324 | IFRET 325 | OVER 326 | SEMPTY ; isEmpty 327 | IFJMPREF { 328 | GETGLOB 6 329 | THROWIFNOT 76 330 | } 331 | OVER 332 | LDUQ 32 ; [funcId] body' ok 333 | THROWIFNOT 60 334 | OVER 335 | IFNOTJMPREF { 336 | GETGLOB 6 337 | THROWIFNOT 76 338 | } 339 | SWAP 340 | CALLREF { 341 | CALL $public_function_selector$ 342 | } 343 | THROW 60 344 | 345 | .internal-alias :main_external, -1 346 | .internal :main_external 347 | PUSHROOT 348 | CTOS 349 | SBITS 350 | NEQINT 1 351 | SETGLOB 6 352 | PUSHREFSLICE { 353 | .blob x8000000000000000000000000000000000000000000000000000000000000000001_ 354 | } 355 | SETGLOB 9 356 | OVER 357 | CALLREF { 358 | CALL $c4_to_c7_with_init_storage$ 359 | } 360 | LDU 1 ; haveSign msgSlice 361 | SWAP 362 | PUSHCONT { 363 | PUSHINT 512 364 | LDSLICEX ; signatureSlice msgSlice 365 | DUP 366 | HASHSU ; signatureSlice msgSlice hashMsgSlice 367 | ROT 368 | GETGLOB 2 369 | CHKSIGNU ; msgSlice isSigned 370 | THROWIFNOT 40 371 | } 372 | IF 373 | LDU 64 ; timestamp msgSlice 374 | SWAP 375 | CALL $replay_protection_macro$ 376 | LDU 32 ; funcId body 377 | SWAP 378 | CALLREF { 379 | CALL $public_function_selector$ 380 | } 381 | THROW 60 382 | 383 | .macro public_function_selector 384 | DUP 385 | PUSHINT 362821883 386 | EQUAL 387 | IFJMPREF { 388 | CALL $constructor$ 389 | } 390 | 391 | -------------------------------------------------------------------------------- /build/TokenWalletPlatform.tvc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/venom-blockchain/vesting/47c022404231af7d4f309a3dc2c70ea5e9017501/build/TokenWalletPlatform.tvc -------------------------------------------------------------------------------- /build/TokenWalletUpgradeable.abi.json: -------------------------------------------------------------------------------- 1 | { 2 | "ABI version": 2, 3 | "version": "2.2", 4 | "header": ["pubkey", "time", "expire"], 5 | "functions": [ 6 | { 7 | "name": "constructor", 8 | "inputs": [ 9 | ], 10 | "outputs": [ 11 | ] 12 | }, 13 | { 14 | "name": "supportsInterface", 15 | "inputs": [ 16 | {"name":"answerId","type":"uint32"}, 17 | {"name":"interfaceID","type":"uint32"} 18 | ], 19 | "outputs": [ 20 | {"name":"value0","type":"bool"} 21 | ] 22 | }, 23 | { 24 | "name": "platformCode", 25 | "inputs": [ 26 | {"name":"answerId","type":"uint32"} 27 | ], 28 | "outputs": [ 29 | {"name":"value0","type":"cell"} 30 | ] 31 | }, 32 | { 33 | "name": "onDeployRetry", 34 | "id": "0x15A038FB", 35 | "inputs": [ 36 | {"name":"value0","type":"cell"}, 37 | {"name":"value1","type":"uint32"}, 38 | {"name":"sender","type":"address"}, 39 | {"name":"remainingGasTo","type":"address"} 40 | ], 41 | "outputs": [ 42 | ] 43 | }, 44 | { 45 | "name": "version", 46 | "inputs": [ 47 | {"name":"answerId","type":"uint32"} 48 | ], 49 | "outputs": [ 50 | {"name":"value0","type":"uint32"} 51 | ] 52 | }, 53 | { 54 | "name": "upgrade", 55 | "inputs": [ 56 | {"name":"remainingGasTo","type":"address"} 57 | ], 58 | "outputs": [ 59 | ] 60 | }, 61 | { 62 | "name": "acceptUpgrade", 63 | "inputs": [ 64 | {"name":"newCode","type":"cell"}, 65 | {"name":"newVersion","type":"uint32"}, 66 | {"name":"remainingGasTo","type":"address"} 67 | ], 68 | "outputs": [ 69 | ] 70 | }, 71 | { 72 | "name": "burnByRoot", 73 | "inputs": [ 74 | {"name":"amount","type":"uint128"}, 75 | {"name":"remainingGasTo","type":"address"}, 76 | {"name":"callbackTo","type":"address"}, 77 | {"name":"payload","type":"cell"} 78 | ], 79 | "outputs": [ 80 | ] 81 | }, 82 | { 83 | "name": "destroy", 84 | "inputs": [ 85 | {"name":"remainingGasTo","type":"address"} 86 | ], 87 | "outputs": [ 88 | ] 89 | }, 90 | { 91 | "name": "burn", 92 | "inputs": [ 93 | {"name":"amount","type":"uint128"}, 94 | {"name":"remainingGasTo","type":"address"}, 95 | {"name":"callbackTo","type":"address"}, 96 | {"name":"payload","type":"cell"} 97 | ], 98 | "outputs": [ 99 | ] 100 | }, 101 | { 102 | "name": "balance", 103 | "inputs": [ 104 | {"name":"answerId","type":"uint32"} 105 | ], 106 | "outputs": [ 107 | {"name":"value0","type":"uint128"} 108 | ] 109 | }, 110 | { 111 | "name": "owner", 112 | "inputs": [ 113 | {"name":"answerId","type":"uint32"} 114 | ], 115 | "outputs": [ 116 | {"name":"value0","type":"address"} 117 | ] 118 | }, 119 | { 120 | "name": "root", 121 | "inputs": [ 122 | {"name":"answerId","type":"uint32"} 123 | ], 124 | "outputs": [ 125 | {"name":"value0","type":"address"} 126 | ] 127 | }, 128 | { 129 | "name": "walletCode", 130 | "inputs": [ 131 | {"name":"answerId","type":"uint32"} 132 | ], 133 | "outputs": [ 134 | {"name":"value0","type":"cell"} 135 | ] 136 | }, 137 | { 138 | "name": "transfer", 139 | "inputs": [ 140 | {"name":"amount","type":"uint128"}, 141 | {"name":"recipient","type":"address"}, 142 | {"name":"deployWalletValue","type":"uint128"}, 143 | {"name":"remainingGasTo","type":"address"}, 144 | {"name":"notify","type":"bool"}, 145 | {"name":"payload","type":"cell"} 146 | ], 147 | "outputs": [ 148 | ] 149 | }, 150 | { 151 | "name": "transferToWallet", 152 | "inputs": [ 153 | {"name":"amount","type":"uint128"}, 154 | {"name":"recipientTokenWallet","type":"address"}, 155 | {"name":"remainingGasTo","type":"address"}, 156 | {"name":"notify","type":"bool"}, 157 | {"name":"payload","type":"cell"} 158 | ], 159 | "outputs": [ 160 | ] 161 | }, 162 | { 163 | "name": "acceptTransfer", 164 | "id": "0x67A0B95F", 165 | "inputs": [ 166 | {"name":"amount","type":"uint128"}, 167 | {"name":"sender","type":"address"}, 168 | {"name":"remainingGasTo","type":"address"}, 169 | {"name":"notify","type":"bool"}, 170 | {"name":"payload","type":"cell"} 171 | ], 172 | "outputs": [ 173 | ] 174 | }, 175 | { 176 | "name": "acceptMint", 177 | "id": "0x4384F298", 178 | "inputs": [ 179 | {"name":"amount","type":"uint128"}, 180 | {"name":"remainingGasTo","type":"address"}, 181 | {"name":"notify","type":"bool"}, 182 | {"name":"payload","type":"cell"} 183 | ], 184 | "outputs": [ 185 | ] 186 | }, 187 | { 188 | "name": "sendSurplusGas", 189 | "inputs": [ 190 | {"name":"to","type":"address"} 191 | ], 192 | "outputs": [ 193 | ] 194 | } 195 | ], 196 | "data": [ 197 | {"key":1,"name":"root_","type":"address"}, 198 | {"key":2,"name":"owner_","type":"address"} 199 | ], 200 | "events": [ 201 | ], 202 | "fields": [ 203 | {"name":"_pubkey","type":"uint256"}, 204 | {"name":"_timestamp","type":"uint64"}, 205 | {"name":"_constructorFlag","type":"bool"}, 206 | {"name":"root_","type":"address"}, 207 | {"name":"owner_","type":"address"}, 208 | {"name":"balance_","type":"uint128"}, 209 | {"name":"version_","type":"uint32"}, 210 | {"name":"platformCode_","type":"cell"} 211 | ] 212 | } 213 | -------------------------------------------------------------------------------- /build/TokenWalletUpgradeable.base64: -------------------------------------------------------------------------------- 1 | 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 66 | -------------------------------------------------------------------------------- /build/TokenWalletUpgradeable.tvc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/venom-blockchain/vesting/47c022404231af7d4f309a3dc2c70ea5e9017501/build/TokenWalletUpgradeable.tvc -------------------------------------------------------------------------------- /build/Vesting.abi.json: -------------------------------------------------------------------------------- 1 | { 2 | "ABI version": 2, 3 | "version": "2.2", 4 | "header": ["time", "expire"], 5 | "functions": [ 6 | { 7 | "name": "constructor", 8 | "inputs": [ 9 | {"name":"_user","type":"address"}, 10 | {"name":"_creator","type":"address"}, 11 | {"name":"_remainingGasTo","type":"address"}, 12 | {"name":"_token","type":"address"}, 13 | {"name":"_vestingAmount","type":"uint128"}, 14 | {"name":"_vestingStart","type":"uint32"}, 15 | {"name":"_vestingEnd","type":"uint32"} 16 | ], 17 | "outputs": [ 18 | ] 19 | }, 20 | { 21 | "name": "receiveTokenWalletAddress", 22 | "inputs": [ 23 | {"name":"wallet","type":"address"} 24 | ], 25 | "outputs": [ 26 | ] 27 | }, 28 | { 29 | "name": "dummy", 30 | "inputs": [ 31 | {"name":"value0","type":"address"} 32 | ], 33 | "outputs": [ 34 | ] 35 | }, 36 | { 37 | "name": "getDetails", 38 | "inputs": [ 39 | ], 40 | "outputs": [ 41 | {"name":"_user","type":"address"}, 42 | {"name":"_creator","type":"address"}, 43 | {"name":"_token","type":"address"}, 44 | {"name":"_vestingAmount","type":"uint128"}, 45 | {"name":"_vestingStart","type":"uint32"}, 46 | {"name":"_vestingEnd","type":"uint32"}, 47 | {"name":"_lastClaimTime","type":"uint32"}, 48 | {"name":"_tokenBalance","type":"uint128"}, 49 | {"name":"_tokenWallet","type":"address"}, 50 | {"name":"_filled","type":"bool"}, 51 | {"name":"_vested","type":"bool"}, 52 | {"name":"_nonce","type":"uint128"}, 53 | {"name":"_factory","type":"address"} 54 | ] 55 | }, 56 | { 57 | "name": "onAcceptTokensTransfer", 58 | "inputs": [ 59 | {"name":"value0","type":"address"}, 60 | {"name":"amount","type":"uint128"}, 61 | {"name":"sender","type":"address"}, 62 | {"name":"value3","type":"address"}, 63 | {"name":"remainingGasTo","type":"address"}, 64 | {"name":"value5","type":"cell"} 65 | ], 66 | "outputs": [ 67 | ] 68 | }, 69 | { 70 | "name": "pendingVested", 71 | "inputs": [ 72 | ], 73 | "outputs": [ 74 | {"name":"tokens_to_claim","type":"uint128"} 75 | ] 76 | }, 77 | { 78 | "name": "claim", 79 | "inputs": [ 80 | ], 81 | "outputs": [ 82 | ] 83 | } 84 | ], 85 | "data": [ 86 | {"key":1,"name":"nonce","type":"uint128"}, 87 | {"key":2,"name":"factory","type":"address"} 88 | ], 89 | "events": [ 90 | { 91 | "name": "ReceivedTokenWalletAddress", 92 | "inputs": [ 93 | {"name":"wallet","type":"address"} 94 | ], 95 | "outputs": [ 96 | ] 97 | }, 98 | { 99 | "name": "Deposit", 100 | "inputs": [ 101 | {"name":"sender","type":"address"}, 102 | {"name":"amount","type":"uint128"} 103 | ], 104 | "outputs": [ 105 | ] 106 | }, 107 | { 108 | "name": "BadDeposit", 109 | "inputs": [ 110 | {"name":"sender","type":"address"}, 111 | {"name":"amount","type":"uint128"} 112 | ], 113 | "outputs": [ 114 | ] 115 | }, 116 | { 117 | "name": "Claim", 118 | "inputs": [ 119 | {"name":"amount","type":"uint128"}, 120 | {"name":"remaining_amount","type":"uint128"} 121 | ], 122 | "outputs": [ 123 | ] 124 | }, 125 | { 126 | "name": "Vested", 127 | "inputs": [ 128 | ], 129 | "outputs": [ 130 | ] 131 | } 132 | ], 133 | "fields": [ 134 | {"name":"_pubkey","type":"uint256"}, 135 | {"name":"_timestamp","type":"uint64"}, 136 | {"name":"_constructorFlag","type":"bool"}, 137 | {"name":"nonce","type":"uint128"}, 138 | {"name":"factory","type":"address"}, 139 | {"name":"user","type":"address"}, 140 | {"name":"creator","type":"address"}, 141 | {"name":"token","type":"address"}, 142 | {"name":"vestingAmount","type":"uint128"}, 143 | {"name":"vestingStart","type":"uint32"}, 144 | {"name":"vestingEnd","type":"uint32"}, 145 | {"name":"lastClaimTime","type":"uint32"}, 146 | {"name":"tokenBalance","type":"uint128"}, 147 | {"name":"tokenWallet","type":"address"}, 148 | {"name":"filled","type":"bool"}, 149 | {"name":"vested","type":"bool"} 150 | ] 151 | } 152 | -------------------------------------------------------------------------------- /build/Vesting.base64: -------------------------------------------------------------------------------- 1 | te6ccgECKAEABt8AAgE0AwEBAcACAEPQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgBCSK7VMg4wMgwP/jAiDA/uMC8gslBQQnA5jtRNDXScMB+GaJ+Gkh2zzTAAGegwjXGCD5AVj4QvkQ8qje0z8B+EMhufK0IPgjgQPoqIIIG3dAoLnytPhj0x8B+CO88rnTHwHbPPI8ExAGA1LtRNDXScMB+GYi0NMD+kAw+GmpOADcIccA4wIh1w0f8rwh4wMB2zzyPCQkBgIoIIIQUL/Kn7vjAiCCEH+duES74wIUBwM8IIIQcJIOMrrjAiCCEHDYn8m64wIgghB/nbhEuuMCDQoIA2gw+Eby4Ez4Qm7jANHbPCGOHCPQ0wH6QDAxyM+HIM6CEP+duETPC4HLf8lw+wCRMOLjAPIAIwkhAFhw+CP4Ub6TMPhTjh/4I/hSvo4X+FH4UqG1H/gj+FKhtR/4U6i1fwGpBDHe4gNaMPhG8uBM+EJu4wAhk9TR0N76QNN/1NHQ+kDU0dD6QNTR0PpA1NHbPDDbPPIAIwsYApww+En4VMcF8uPr2zxw+wIj+E+9+FV/urGOgOAj+HN/+HVajQRwAAAAAAAAAAAAAAAAFfyAtmDIzs7Lf8lw+wDIz4UIzoBvz0DJgwb7AFsdDAGcXY0EcAAAAAAAAAAAAAAAAB5FF69gyM7Oy3/JcPsAiHAkcFUVAfhUyM+FiM5xzwtuVVDIz5HPiIUOy3/Oy39VIMjOygDMzc3Jgwb7AF8DJwT+MPhCbuMA+EbycyGT1NHQ3vpA1NHQ+kDU0dD6QNTR0PpA03/TH9Mf0fhJ+EvHBfLj6ts8cPsCVQX4bFUE+G1VAvhuWPhvAfhw+HH4UPhy2zz4UfhQ+E/4TlUD+E34TPhK+EvIz4WIznHPC25VcMjPkMQljk7Lf85VUMjOVUDIzhAdDw4BLlUwyM7Lf8sfyx/Nzc3NyYMG+wDbPPIAGADsghAO5rKA+Cj4TsjPhYjOgoAg7msoAAAAAAAAAAAAAAAAAAHPC45Zi4Me3Ux1C/yp+MjOzst/zclw+wCCEA7msoD4TPhOyM+FiM6CgCDuaygAAAAAAAAAAAAAAAAAAc8LjlmLgx7dTHQHUIx4yM7Oy3/NyXD7AAIW7UTQ10nCAY6A4w0RIwOacO1E0PQFcSGAQPQOb5GT1wt/3nIigED0Do6A34lfIHBfQIlwIPh2+HX4dPhz+HL4cfhw+G/4bvht+Gz4a/hqgED0DvK91wv/+GJw+GMSExMBAokTAEOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQBFAgghAgEhXOuuMCIIIQQHUIx7rjAiCCEELFMHC64wIgghBQv8qfuuMCIB4XFQM2MPhG8uBM+EJu4wAhk9TR0N76QNHbPDDbPPIAIxYYAE74SfhOxwXy4/Ag+HSNBHAAAAAAAAAAAAAAAAAGT3FloMjOzslw+wADJjD4RvLgTPhCbuMA0ds8MNs88gAjGRgAovhW+FX4VPhT+FL4UfhQ+E/4TvhN+Ez4S/hK+EP4QsjL/8s/z4PLf1WwyM5VoMjOVZDIzlWAyM7Lf8sfyx/LH8t/VSDIzsoAygDNzc3NzcntVAL++En4TMcF8uPp+CP4UL7y4+z4VX+68uPt+FZwuvLj7mim/mCCEDuaygC+8uPv2zxw+wJw+CP4Ub6TMPhTjhf4UfhSobUf+CP4UqG1H/hTqLV/AakEMeL4UyGhtX/4c/gj+HL4UyGNBHAAAAAAAAAAAAAAAAAdD4bvoMjOy3/Lfx0aAnLJcPsA+FOOgN+IcPhMcPhMVQT4VMjPhYjOcc8LblVQyM+Rz4iFDst/zst/VSDIzsoAzM3NyYMG+wAbJwEOf/h2iHD7ABwAIsAAAAAAAAAAAAAAAABsc0wbACb4J28QaKb+YKG1f4IQO5rKALYJAzQw+Eby4Ez4Qm7jACGT1NHQ3vpA0ds84wDyACMfIQAUMPhJ+E7HBfLj8AO4MPhG8uBM+EJu4wDR2zwtjkMv0NMB+kAwMcjPhyDOcc8LYV7AyM+SgEhXOs5VsMjOVaDIzst/yx/LH8sfy39VQMjOygDKAMt/AcjOzc3Nzc3JcPsAkl8N4uMA8gAjIiEAKO1E0NP/0z8x+ENYyMv/yz/Oye1UADT4TPhN+E74T/hQ+FH4UvhT+FT4VfhW+Er4SwCk7UTQ0//TP9MAMdN/1NHQ+kDU0dD6QNTR0PpA1NHQ+kDTf9Mf0x/TH9N/1NHQ+kDSANIA0fh2+HX4dPhz+HL4cfhw+G/4bvht+Gz4a/hq+GP4YgAK+Eby4EwCCvSkIPShJyYAFHNvbCAwLjYyLjAAAA== -------------------------------------------------------------------------------- /build/Vesting.tvc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/venom-blockchain/vesting/47c022404231af7d4f309a3dc2c70ea5e9017501/build/Vesting.tvc -------------------------------------------------------------------------------- /build/VestingFactory.abi.json: -------------------------------------------------------------------------------- 1 | { 2 | "ABI version": 2, 3 | "version": "2.2", 4 | "header": ["pubkey", "time", "expire"], 5 | "functions": [ 6 | { 7 | "name": "constructor", 8 | "inputs": [ 9 | {"name":"indexCode","type":"cell"}, 10 | {"name":"indexDeployValue","type":"uint128"}, 11 | {"name":"indexDestroyValue","type":"uint128"} 12 | ], 13 | "outputs": [ 14 | ] 15 | }, 16 | { 17 | "name": "deployNativeVesting", 18 | "inputs": [ 19 | {"name":"user","type":"address"}, 20 | {"name":"remainingGasTo","type":"address"}, 21 | {"name":"vesting_amount","type":"uint128"}, 22 | {"name":"vesting_start","type":"uint32"}, 23 | {"name":"vesting_end","type":"uint32"} 24 | ], 25 | "outputs": [ 26 | ] 27 | }, 28 | { 29 | "name": "deployVesting", 30 | "inputs": [ 31 | {"name":"user","type":"address"}, 32 | {"name":"remainingGasTo","type":"address"}, 33 | {"name":"token","type":"address"}, 34 | {"name":"vesting_amount","type":"uint128"}, 35 | {"name":"vesting_start","type":"uint32"}, 36 | {"name":"vesting_end","type":"uint32"} 37 | ], 38 | "outputs": [ 39 | ] 40 | }, 41 | { 42 | "name": "onVestingDeployed", 43 | "inputs": [ 44 | {"name":"nonce","type":"uint128"}, 45 | {"name":"user","type":"address"}, 46 | {"name":"creator","type":"address"}, 47 | {"name":"remainingGasTo","type":"address"}, 48 | {"name":"token","type":"address"}, 49 | {"name":"vesting_amount","type":"uint128"}, 50 | {"name":"vesting_start","type":"uint32"}, 51 | {"name":"vesting_end","type":"uint32"} 52 | ], 53 | "outputs": [ 54 | ] 55 | }, 56 | { 57 | "name": "getIndexCode", 58 | "inputs": [ 59 | {"name":"answerId","type":"uint32"} 60 | ], 61 | "outputs": [ 62 | {"name":"value0","type":"cell"} 63 | ] 64 | }, 65 | { 66 | "name": "resolveIndexCodeHash", 67 | "inputs": [ 68 | {"name":"answerId","type":"uint32"}, 69 | {"name":"saltKey","type":"string"}, 70 | {"name":"saltValue","type":"cell"} 71 | ], 72 | "outputs": [ 73 | {"name":"value0","type":"uint256"} 74 | ] 75 | }, 76 | { 77 | "name": "deploy_nonce", 78 | "inputs": [ 79 | ], 80 | "outputs": [ 81 | {"name":"deploy_nonce","type":"uint128"} 82 | ] 83 | }, 84 | { 85 | "name": "vestings_deployed", 86 | "inputs": [ 87 | ], 88 | "outputs": [ 89 | {"name":"vestings_deployed","type":"uint128"} 90 | ] 91 | } 92 | ], 93 | "data": [ 94 | {"key":1,"name":"deploy_nonce","type":"uint128"}, 95 | {"key":2,"name":"vestingCode","type":"cell"}, 96 | {"key":3,"name":"nativeVestingCode","type":"cell"} 97 | ], 98 | "events": [ 99 | { 100 | "name": "NewVesting", 101 | "inputs": [ 102 | {"name":"vesting","type":"address"}, 103 | {"name":"user","type":"address"}, 104 | {"name":"creator","type":"address"}, 105 | {"name":"token","type":"address"}, 106 | {"name":"amount","type":"uint128"}, 107 | {"name":"start","type":"uint32"}, 108 | {"name":"end","type":"uint32"} 109 | ], 110 | "outputs": [ 111 | ] 112 | }, 113 | { 114 | "name": "IndexDeployed", 115 | "inputs": [ 116 | {"name":"index","type":"address"}, 117 | {"name":"indexedContract","type":"address"}, 118 | {"name":"indexCodeHash","type":"uint256"}, 119 | {"name":"saltKey","type":"string"}, 120 | {"name":"saltValue","type":"cell"} 121 | ], 122 | "outputs": [ 123 | ] 124 | } 125 | ], 126 | "fields": [ 127 | {"name":"_pubkey","type":"uint256"}, 128 | {"name":"_timestamp","type":"uint64"}, 129 | {"name":"_constructorFlag","type":"bool"}, 130 | {"name":"_indexDeployValue","type":"uint128"}, 131 | {"name":"_indexDestroyValue","type":"uint128"}, 132 | {"name":"_indexCode","type":"cell"}, 133 | {"name":"deploy_nonce","type":"uint128"}, 134 | {"name":"vestingCode","type":"cell"}, 135 | {"name":"nativeVestingCode","type":"cell"}, 136 | {"name":"vestings_deployed","type":"uint128"} 137 | ] 138 | } 139 | -------------------------------------------------------------------------------- /build/VestingFactory.base64: -------------------------------------------------------------------------------- 1 | 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 -------------------------------------------------------------------------------- /build/VestingFactory.tvc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/venom-blockchain/vesting/47c022404231af7d4f309a3dc2c70ea5e9017501/build/VestingFactory.tvc -------------------------------------------------------------------------------- /build/Wallet.abi.json: -------------------------------------------------------------------------------- 1 | { 2 | "ABI version": 2, 3 | "version": "2.2", 4 | "header": ["pubkey", "time", "expire"], 5 | "functions": [ 6 | { 7 | "name": "sendTransaction", 8 | "inputs": [ 9 | {"name":"dest","type":"address"}, 10 | {"name":"value","type":"uint128"}, 11 | {"name":"bounce","type":"bool"}, 12 | {"name":"flags","type":"uint8"}, 13 | {"name":"payload","type":"cell"} 14 | ], 15 | "outputs": [ 16 | ] 17 | }, 18 | { 19 | "name": "transferOwnership", 20 | "inputs": [ 21 | {"name":"newOwner","type":"uint256"} 22 | ], 23 | "outputs": [ 24 | ] 25 | }, 26 | { 27 | "name": "constructor", 28 | "inputs": [ 29 | ], 30 | "outputs": [ 31 | ] 32 | }, 33 | { 34 | "name": "owner", 35 | "inputs": [ 36 | ], 37 | "outputs": [ 38 | {"name":"owner","type":"uint256"} 39 | ] 40 | }, 41 | { 42 | "name": "_randomNonce", 43 | "inputs": [ 44 | ], 45 | "outputs": [ 46 | {"name":"_randomNonce","type":"uint256"} 47 | ] 48 | } 49 | ], 50 | "data": [ 51 | {"key":1,"name":"_randomNonce","type":"uint256"} 52 | ], 53 | "events": [ 54 | { 55 | "name": "OwnershipTransferred", 56 | "inputs": [ 57 | {"name":"previousOwner","type":"uint256"}, 58 | {"name":"newOwner","type":"uint256"} 59 | ], 60 | "outputs": [ 61 | ] 62 | } 63 | ], 64 | "fields": [ 65 | {"name":"_pubkey","type":"uint256"}, 66 | {"name":"_timestamp","type":"uint64"}, 67 | {"name":"_constructorFlag","type":"bool"}, 68 | {"name":"owner","type":"uint256"}, 69 | {"name":"_randomNonce","type":"uint256"} 70 | ] 71 | } 72 | -------------------------------------------------------------------------------- /build/Wallet.base64: -------------------------------------------------------------------------------- 1 | te6ccgECGAEAAuQAAgE0AwEBAcACAEPQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgBCSK7VMg4wMgwP/jAiDA/uMC8gsVBQQXArztRNDXScMB+GYh2zzTAAGOHIMI1xgg+QEB0wABlNP/AwGTAvhC4iD4ZfkQ8qiV0wAB8nri0z8B+EMhufK0IPgjgQPoqIIIG3dAoLnytPhj0x8B+CO88rnTHwHbPPI8CAYDSu1E0NdJwwH4ZiLQ1wsDqTgA3CHHAOMCIdcNH/K8IeMDAds88jwUFAYCKCCCEFhakGS74wIgghBotV8/uuMCCQcDUjD4Qm7jAPhG8nPR+EUgbpIwcN74Qrry5E/4APhFIG6SMHDe2zzbPPIACA0LAWLtRNDXScIBjiZw7UTQ9AVwcSKAQPQOb5GT1wv/3vhr+GqAQPQO8r3XC//4YnD4Y+MNEwRQIIIQEXjpvbrjAiCCEDtTMx+64wIgghBM7mRsuuMCIIIQWFqQZLrjAhIRDgoDNjD4RvLgTPhCbuMAIZPU0dDe0//R2zww2zzyABMMCwAs+Ev4SvhD+ELIy//LP8+Dy//L/8ntVAEs+EUgbpIwcN74Srry5E0g8uRO+ADbPA0ARvhKIfhqjQRwAAAAAAAAAAAAAAAAFNs0/KDIzsv/y//JcPsAA0Iw+Eby4Ez4Qm7jACGT1NHQ3vpA03/SANMH1NHbPOMA8gATEA8AKO1E0NP/0z8x+ENYyMv/yz/Oye1UAFT4RSBukjBw3vhKuvLkTfgAVQJVEsjPhYDKAM+EQM4B+gJxzwtqzMkB+wABUDDR2zz4SyGOHI0EcAAAAAAAAAAAAAAAAC7UzMfgyM7L/8lw+wDe8gATAVAw0ds8+EohjhyNBHAAAAAAAAAAAAAAAAAkXjpvYMjOy//JcPsA3vIAEwAu7UTQ0//TP9MAMdP/0//R+Gv4avhj+GIACvhG8uBMAgr0pCD0oRcWABRzb2wgMC42Mi4wAAA= -------------------------------------------------------------------------------- /build/Wallet.code: -------------------------------------------------------------------------------- 1 | .version sol 0.62.0 2 | 3 | .macro constructor 4 | DROP 5 | GETGLOB 2 6 | ISNULL 7 | IFREF { 8 | CALL $c4_to_c7_with_init_storage$ 9 | } 10 | GETGLOB 6 11 | THROWIF 51 12 | ENDS 13 | .loc ../node_modules/@broxus/contracts/contracts/utils/CheckPubKey.tsol, 9 14 | GETGLOB 5 15 | DUP 16 | ISNULL 17 | PUSHCONT { 18 | DROP 19 | PUSHINT 0 20 | } 21 | IF 22 | GETGLOB 2 23 | EQUAL 24 | THROWIFNOT 1103 25 | .loc ../node_modules/@broxus/contracts/contracts/wallets/Account.tsol, 18 26 | ACCEPT 27 | .loc ../node_modules/@broxus/contracts/contracts/wallets/Account.tsol, 20 28 | GETGLOB 5 29 | DUP 30 | ISNULL 31 | PUSHCONT { 32 | DROP 33 | PUSHINT 0 34 | } 35 | IF 36 | CALLREF { 37 | CALL $setOwnership_3e1af783_internal_macro$ 38 | } 39 | .loc ../node_modules/@broxus/contracts/contracts/utils/CheckPubKey.tsol, 0 40 | CALLREF { 41 | CALL $c7_to_c4$ 42 | } 43 | THROW 0 44 | 45 | .macro sendTransaction 46 | DROP 47 | GETGLOB 6 48 | THROWIFNOT 76 49 | GETGLOB 2 50 | ISNULL 51 | IFREF { 52 | CALL $c4_to_c7$ 53 | } 54 | .loc ../node_modules/@broxus/contracts/contracts/wallets/Account.tsol, 31 55 | OVER 56 | PUSHCONT { 57 | LDREF 58 | ENDS 59 | CTOS 60 | } 61 | IF 62 | LDMSGADDR 63 | LDU 128 64 | LDI 1 65 | LDU 8 66 | LDREF 67 | ENDS 68 | .loc ../node_modules/@broxus/contracts/contracts/wallets/Account.tsol, 0 69 | CALLREF { 70 | CALL $sendTransaction_c96c9ed1_internal_macro$ 71 | } 72 | IFREF { 73 | CALL $upd_only_time_in_c4$ 74 | } 75 | THROW 0 76 | 77 | .globl sendTransaction_c96c9ed1_internal 78 | .type sendTransaction_c96c9ed1_internal, @function 79 | CALL $sendTransaction_c96c9ed1_internal_macro$ 80 | 81 | .macro sendTransaction_c96c9ed1_internal_macro 82 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 14 83 | GETGLOB 5 84 | DUP 85 | ISNULL 86 | PUSHCONT { 87 | DROP 88 | PUSHINT 0 89 | } 90 | IF 91 | GETGLOB 10 92 | EQUAL 93 | THROWIFNOT 1101 94 | .loc ../node_modules/@broxus/contracts/contracts/wallets/Account.tsol, 42 95 | ACCEPT 96 | .loc ../node_modules/@broxus/contracts/contracts/wallets/Account.tsol, 44 97 | ROLL 3 98 | BLKSWAP 2, 3 99 | NEWC 100 | STSLICECONST x6_ 101 | STI 1 102 | STSLICECONST x1_ 103 | STSLICE 104 | SWAP 105 | STGRAMS 106 | PUSHINT 1 107 | STUR 107 108 | STREF 109 | ENDC 110 | SWAP 111 | SENDRAWMSG 112 | .loc ../node_modules/@broxus/contracts/contracts/wallets/Account.tsol, 0 113 | 114 | .globl setOwnership_3e1af783_internal 115 | .type setOwnership_3e1af783_internal, @function 116 | CALL $setOwnership_3e1af783_internal_macro$ 117 | 118 | .macro setOwnership_3e1af783_internal_macro 119 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 23 120 | GETGLOB 10 121 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 25 122 | OVER 123 | SETGLOB 10 124 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 27 125 | PUSHSLICE xc0000000000000000000000000536cd3f2 126 | NEWC 127 | STSLICE 128 | STU 256 129 | STU 256 130 | ENDC 131 | PUSHINT 0 132 | SENDRAWMSG 133 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 0 134 | 135 | .macro transferOwnership 136 | DROP 137 | GETGLOB 6 138 | THROWIFNOT 76 139 | GETGLOB 2 140 | ISNULL 141 | IFREF { 142 | CALL $c4_to_c7$ 143 | } 144 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 33 145 | OVER 146 | PUSHCONT { 147 | LDREF 148 | ENDS 149 | CTOS 150 | } 151 | IF 152 | LDU 256 153 | ENDS 154 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 0 155 | CALLREF { 156 | CALL $transferOwnership_d23e8489_internal_macro$ 157 | } 158 | DROP 159 | CALLREF { 160 | CALL $c7_to_c4$ 161 | } 162 | THROW 0 163 | 164 | .macro transferOwnership_d23e8489_internal_macro 165 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 14 166 | GETGLOB 5 167 | DUP 168 | ISNULL 169 | PUSHCONT { 170 | DROP 171 | PUSHINT 0 172 | } 173 | IF 174 | GETGLOB 10 175 | EQUAL 176 | THROWIFNOT 1101 177 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 36 178 | DUP 179 | THROWIFNOT 1102 180 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 37 181 | ACCEPT 182 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 39 183 | CALLREF { 184 | CALL $setOwnership_3e1af783_internal_macro$ 185 | } 186 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 0 187 | 188 | .macro c4_to_c7 189 | PUSHROOT 190 | CTOS 191 | LDU 256 ; pubkey c4 192 | LDU 64 ; pubkey timestamp c4 193 | LDU 1 ; ctor flag 194 | NIP 195 | LDU 256 196 | LDU 256 197 | ENDS 198 | SETGLOB 11 199 | SETGLOB 10 200 | SETGLOB 3 201 | SETGLOB 2 202 | 203 | .macro c4_to_c7_with_init_storage 204 | PUSHROOT 205 | CTOS 206 | SBITS 207 | GTINT 1 208 | PUSHCONT { 209 | PUSHINT 0 210 | PUSHROOT 211 | CTOS 212 | PLDDICT ; D 213 | PUSHINT 0 214 | PUSHINT 1 215 | PUSH S2 216 | PUSHINT 64 217 | DICTUGET 218 | ZEROSWAPIFNOT 219 | PUSHCONT { 220 | PLDU 256 221 | } 222 | IF 223 | SETGLOB 11 224 | SETGLOB 10 225 | PUSHINT 64 226 | DICTUGET 227 | THROWIFNOT 61 228 | PLDU 256 229 | SETGLOB 2 230 | PUSHINT 0 ; timestamp 231 | SETGLOB 3 232 | } 233 | IFREFELSE { 234 | CALL $c4_to_c7$ 235 | } 236 | 237 | .macro c7_to_c4 238 | GETGLOB 11 239 | GETGLOB 10 240 | GETGLOB 3 241 | GETGLOB 2 242 | NEWC 243 | STU 256 244 | STU 64 245 | STONE 246 | STU 256 247 | STU 256 248 | ENDC 249 | POPROOT 250 | 251 | .macro upd_only_time_in_c4 252 | PUSHROOT 253 | CTOS 254 | LDU 256 255 | LDU 64 256 | NIP 257 | GETGLOB 3 258 | ROT 259 | NEWC 260 | STU 256 261 | STU 64 262 | STSLICE 263 | ENDC 264 | POPROOT 265 | 266 | .internal-alias :main_internal, 0 267 | .internal :main_internal 268 | PUSHROOT 269 | CTOS 270 | SBITS 271 | NEQINT 1 272 | SETGLOB 6 273 | PUSH S2 274 | CTOS 275 | PLDU 4 276 | MODPOW2 1 277 | IFRET 278 | OVER 279 | SEMPTY ; isEmpty 280 | IFJMPREF { 281 | GETGLOB 6 282 | THROWIFNOT 76 283 | } 284 | OVER 285 | LDUQ 32 ; [funcId] body' ok 286 | THROWIFNOT 60 287 | OVER 288 | IFNOTJMPREF { 289 | GETGLOB 6 290 | THROWIFNOT 76 291 | } 292 | SWAP 293 | CALLREF { 294 | CALL $public_function_selector$ 295 | } 296 | THROW 60 297 | 298 | .internal-alias :main_external, -1 299 | .internal :main_external 300 | PUSHROOT 301 | CTOS 302 | SBITS 303 | NEQINT 1 304 | SETGLOB 6 305 | OVER 306 | CALLREF { 307 | CALL $c4_to_c7_with_init_storage$ 308 | } 309 | LDU 1 ; haveSign msgSlice 310 | SWAP 311 | PUSHCONT { 312 | PUSHPOW2 9 313 | LDSLICEX ; signatureSlice msgSlice 314 | DUP 315 | HASHSU ; signatureSlice msgSlice hashMsgSlice 316 | SWAP 317 | LDU 1 ; signatureSlice hashMsgSlice hasPubkey msgSlice 318 | SWAP 319 | PUSHCONT { 320 | LDU 256 ; signatureSlice hashMsgSlice pubkey msgSlice 321 | XCHG S3 322 | SWAP 323 | } 324 | PUSHCONT { 325 | XCHG S2 326 | GETGLOB 2 327 | } 328 | IFELSE 329 | DUP 330 | SETGLOB 5 331 | CHKSIGNU ; msgSlice isSigned 332 | THROWIFNOT 40 333 | } 334 | PUSHCONT { 335 | LDU 1 ; hasPubkey msgSlice 336 | SWAP 337 | THROWIF 58 338 | } 339 | IFELSE 340 | LDU 64 ; timestamp msgSlice 341 | SWAP 342 | CALL $replay_protection_macro$ 343 | LDU 32 ; expireAt msgSlice 344 | SWAP 345 | NOW ; msgSlice expireAt now 346 | GREATER ; msgSlice expireAt>now 347 | THROWIFNOT 57 348 | LDU 32 ; funcId body 349 | SWAP 350 | CALLREF { 351 | CALL $public_function_selector$ 352 | } 353 | THROW 60 354 | 355 | .macro owner 356 | DROP 357 | ENDS 358 | CALLREF { 359 | CALL $c4_to_c7$ 360 | } 361 | GETGLOB 10 362 | OVER 363 | PUSHCONT { 364 | PUSHSLICE xc00000000000000000000000009178e9bd 365 | NEWC 366 | STSLICE 367 | STU 256 368 | ENDC 369 | PUSHINT 0 370 | SENDRAWMSG 371 | } 372 | IF 373 | THROW 0 374 | 375 | .macro _randomNonce 376 | DROP 377 | ENDS 378 | CALLREF { 379 | CALL $c4_to_c7$ 380 | } 381 | GETGLOB 11 382 | OVER 383 | PUSHCONT { 384 | PUSHSLICE xc0000000000000000000000000bb53331f 385 | NEWC 386 | STSLICE 387 | STU 256 388 | ENDC 389 | PUSHINT 0 390 | SENDRAWMSG 391 | } 392 | IF 393 | THROW 0 394 | 395 | .macro public_function_selector 396 | DUP 397 | PUSHINT 1482330212 398 | LEQ 399 | IFJMPREF { 400 | DUP 401 | PUSHINT 293136829 402 | EQUAL 403 | IFJMPREF { 404 | CALL $owner$ 405 | } 406 | DUP 407 | PUSHINT 995308319 408 | EQUAL 409 | IFJMPREF { 410 | CALL $_randomNonce$ 411 | } 412 | DUP 413 | PUSHINT 1290691692 414 | EQUAL 415 | IFJMPREF { 416 | CALL $sendTransaction$ 417 | } 418 | DUP 419 | PUSHINT 1482330212 420 | EQUAL 421 | IFJMPREF { 422 | CALL $transferOwnership$ 423 | } 424 | } 425 | DUP 426 | PUSHINT 1756716863 427 | EQUAL 428 | IFJMPREF { 429 | CALL $constructor$ 430 | } 431 | 432 | -------------------------------------------------------------------------------- /build/Wallet.tvc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/venom-blockchain/vesting/47c022404231af7d4f309a3dc2c70ea5e9017501/build/Wallet.tvc -------------------------------------------------------------------------------- /build/factorySource.ts: -------------------------------------------------------------------------------- 1 | const indexAbi = {"ABIversion":2,"version":"2.2","header":["pubkey","time","expire"],"functions":[{"name":"constructor","inputs":[],"outputs":[]},{"name":"getIndexedContract","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"address"}]},{"name":"getIndexFactory","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"address"}]},{"name":"getCodeHash","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"uint256"}]},{"name":"destruct","inputs":[{"name":"gasReceiver","type":"address"}],"outputs":[]}],"data":[{"key":1,"name":"_indexedContract","type":"address"},{"key":2,"name":"_saltHash","type":"uint256"}],"events":[],"fields":[{"name":"_pubkey","type":"uint256"},{"name":"_timestamp","type":"uint64"},{"name":"_constructorFlag","type":"bool"},{"name":"_indexedContract","type":"address"},{"name":"_saltHash","type":"uint256"},{"name":"_indexFactory","type":"address"}]} as const 2 | const nativeVestingAbi = {"ABIversion":2,"version":"2.2","header":["time","expire"],"functions":[{"name":"constructor","inputs":[{"name":"_user","type":"address"},{"name":"_creator","type":"address"},{"name":"_remainingGasTo","type":"address"},{"name":"_vestingAmount","type":"uint128"},{"name":"_vestingStart","type":"uint32"},{"name":"_vestingEnd","type":"uint32"}],"outputs":[]},{"name":"getDetails","inputs":[],"outputs":[{"name":"_user","type":"address"},{"name":"_creator","type":"address"},{"name":"_vestingAmount","type":"uint128"},{"name":"_vestingStart","type":"uint32"},{"name":"_vestingEnd","type":"uint32"},{"name":"_lastClaimTime","type":"uint32"},{"name":"_balance","type":"uint128"},{"name":"_filled","type":"bool"},{"name":"_vested","type":"bool"},{"name":"_nonce","type":"uint128"},{"name":"_factory","type":"address"}]},{"name":"deposit","inputs":[{"name":"send_gas_to","type":"address"}],"outputs":[]},{"name":"pendingVested","inputs":[],"outputs":[{"name":"value_to_claim","type":"uint128"}]},{"name":"claim","inputs":[],"outputs":[]}],"data":[{"key":1,"name":"nonce","type":"uint128"},{"key":2,"name":"factory","type":"address"}],"events":[{"name":"Deposit","inputs":[{"name":"sender","type":"address"},{"name":"amount","type":"uint128"}],"outputs":[]},{"name":"Claim","inputs":[{"name":"amount","type":"uint128"},{"name":"remaining_amount","type":"uint128"}],"outputs":[]},{"name":"Vested","inputs":[],"outputs":[]}],"fields":[{"name":"_pubkey","type":"uint256"},{"name":"_timestamp","type":"uint64"},{"name":"_constructorFlag","type":"bool"},{"name":"nonce","type":"uint128"},{"name":"factory","type":"address"},{"name":"user","type":"address"},{"name":"creator","type":"address"},{"name":"vestingAmount","type":"uint128"},{"name":"vestingStart","type":"uint32"},{"name":"vestingEnd","type":"uint32"},{"name":"lastClaimTime","type":"uint32"},{"name":"balance","type":"uint128"},{"name":"filled","type":"bool"},{"name":"vested","type":"bool"}]} as const 3 | const tokenRootUpgradeableAbi = {"ABIversion":2,"version":"2.2","header":["pubkey","time","expire"],"functions":[{"name":"constructor","inputs":[{"name":"initialSupplyTo","type":"address"},{"name":"initialSupply","type":"uint128"},{"name":"deployWalletValue","type":"uint128"},{"name":"mintDisabled","type":"bool"},{"name":"burnByRootDisabled","type":"bool"},{"name":"burnPaused","type":"bool"},{"name":"remainingGasTo","type":"address"}],"outputs":[]},{"name":"supportsInterface","inputs":[{"name":"answerId","type":"uint32"},{"name":"interfaceID","type":"uint32"}],"outputs":[{"name":"value0","type":"bool"}]},{"name":"walletVersion","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"uint32"}]},{"name":"platformCode","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"cell"}]},{"name":"requestUpgradeWallet","inputs":[{"name":"currentVersion","type":"uint32"},{"name":"walletOwner","type":"address"},{"name":"remainingGasTo","type":"address"}],"outputs":[]},{"name":"setWalletCode","inputs":[{"name":"code","type":"cell"}],"outputs":[]},{"name":"upgrade","inputs":[{"name":"code","type":"cell"}],"outputs":[]},{"name":"disableMint","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"bool"}]},{"name":"mintDisabled","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"bool"}]},{"name":"burnTokens","inputs":[{"name":"amount","type":"uint128"},{"name":"walletOwner","type":"address"},{"name":"remainingGasTo","type":"address"},{"name":"callbackTo","type":"address"},{"name":"payload","type":"cell"}],"outputs":[]},{"name":"disableBurnByRoot","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"bool"}]},{"name":"burnByRootDisabled","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"bool"}]},{"name":"burnPaused","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"bool"}]},{"name":"setBurnPaused","inputs":[{"name":"answerId","type":"uint32"},{"name":"paused","type":"bool"}],"outputs":[{"name":"value0","type":"bool"}]},{"name":"transferOwnership","inputs":[{"name":"newOwner","type":"address"},{"name":"remainingGasTo","type":"address"},{"components":[{"name":"value","type":"uint128"},{"name":"payload","type":"cell"}],"name":"callbacks","type":"map(address,tuple)"}],"outputs":[]},{"name":"name","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"string"}]},{"name":"symbol","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"string"}]},{"name":"decimals","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"uint8"}]},{"name":"totalSupply","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"uint128"}]},{"name":"walletCode","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"cell"}]},{"name":"rootOwner","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"address"}]},{"name":"walletOf","inputs":[{"name":"answerId","type":"uint32"},{"name":"walletOwner","type":"address"}],"outputs":[{"name":"value0","type":"address"}]},{"name":"deployWallet","inputs":[{"name":"answerId","type":"uint32"},{"name":"walletOwner","type":"address"},{"name":"deployWalletValue","type":"uint128"}],"outputs":[{"name":"tokenWallet","type":"address"}]},{"name":"mint","inputs":[{"name":"amount","type":"uint128"},{"name":"recipient","type":"address"},{"name":"deployWalletValue","type":"uint128"},{"name":"remainingGasTo","type":"address"},{"name":"notify","type":"bool"},{"name":"payload","type":"cell"}],"outputs":[]},{"name":"acceptBurn","id":"0x192B51B1","inputs":[{"name":"amount","type":"uint128"},{"name":"walletOwner","type":"address"},{"name":"remainingGasTo","type":"address"},{"name":"callbackTo","type":"address"},{"name":"payload","type":"cell"}],"outputs":[]},{"name":"sendSurplusGas","inputs":[{"name":"to","type":"address"}],"outputs":[]}],"data":[{"key":1,"name":"name_","type":"string"},{"key":2,"name":"symbol_","type":"string"},{"key":3,"name":"decimals_","type":"uint8"},{"key":4,"name":"rootOwner_","type":"address"},{"key":5,"name":"walletCode_","type":"cell"},{"key":6,"name":"randomNonce_","type":"uint256"},{"key":7,"name":"deployer_","type":"address"},{"key":8,"name":"platformCode_","type":"cell"}],"events":[],"fields":[{"name":"_pubkey","type":"uint256"},{"name":"_timestamp","type":"uint64"},{"name":"_constructorFlag","type":"bool"},{"name":"name_","type":"string"},{"name":"symbol_","type":"string"},{"name":"decimals_","type":"uint8"},{"name":"rootOwner_","type":"address"},{"name":"walletCode_","type":"cell"},{"name":"totalSupply_","type":"uint128"},{"name":"burnPaused_","type":"bool"},{"name":"burnByRootDisabled_","type":"bool"},{"name":"mintDisabled_","type":"bool"},{"name":"randomNonce_","type":"uint256"},{"name":"deployer_","type":"address"},{"name":"platformCode_","type":"cell"},{"name":"walletVersion_","type":"uint32"}]} as const 4 | const tokenWalletPlatformAbi = {"ABIversion":2,"version":"2.2","header":["time"],"functions":[{"name":"constructor","id":"0x15A038FB","inputs":[{"name":"walletCode","type":"cell"},{"name":"walletVersion","type":"uint32"},{"name":"sender","type":"address"},{"name":"remainingGasTo","type":"address"}],"outputs":[]}],"data":[{"key":1,"name":"root","type":"address"},{"key":2,"name":"owner","type":"address"}],"events":[],"fields":[{"name":"_pubkey","type":"uint256"},{"name":"_timestamp","type":"uint64"},{"name":"_constructorFlag","type":"bool"},{"name":"root","type":"address"},{"name":"owner","type":"address"}]} as const 5 | const tokenWalletUpgradeableAbi = {"ABIversion":2,"version":"2.2","header":["pubkey","time","expire"],"functions":[{"name":"constructor","inputs":[],"outputs":[]},{"name":"supportsInterface","inputs":[{"name":"answerId","type":"uint32"},{"name":"interfaceID","type":"uint32"}],"outputs":[{"name":"value0","type":"bool"}]},{"name":"platformCode","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"cell"}]},{"name":"onDeployRetry","id":"0x15A038FB","inputs":[{"name":"value0","type":"cell"},{"name":"value1","type":"uint32"},{"name":"sender","type":"address"},{"name":"remainingGasTo","type":"address"}],"outputs":[]},{"name":"version","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"uint32"}]},{"name":"upgrade","inputs":[{"name":"remainingGasTo","type":"address"}],"outputs":[]},{"name":"acceptUpgrade","inputs":[{"name":"newCode","type":"cell"},{"name":"newVersion","type":"uint32"},{"name":"remainingGasTo","type":"address"}],"outputs":[]},{"name":"burnByRoot","inputs":[{"name":"amount","type":"uint128"},{"name":"remainingGasTo","type":"address"},{"name":"callbackTo","type":"address"},{"name":"payload","type":"cell"}],"outputs":[]},{"name":"destroy","inputs":[{"name":"remainingGasTo","type":"address"}],"outputs":[]},{"name":"burn","inputs":[{"name":"amount","type":"uint128"},{"name":"remainingGasTo","type":"address"},{"name":"callbackTo","type":"address"},{"name":"payload","type":"cell"}],"outputs":[]},{"name":"balance","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"uint128"}]},{"name":"owner","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"address"}]},{"name":"root","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"address"}]},{"name":"walletCode","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"cell"}]},{"name":"transfer","inputs":[{"name":"amount","type":"uint128"},{"name":"recipient","type":"address"},{"name":"deployWalletValue","type":"uint128"},{"name":"remainingGasTo","type":"address"},{"name":"notify","type":"bool"},{"name":"payload","type":"cell"}],"outputs":[]},{"name":"transferToWallet","inputs":[{"name":"amount","type":"uint128"},{"name":"recipientTokenWallet","type":"address"},{"name":"remainingGasTo","type":"address"},{"name":"notify","type":"bool"},{"name":"payload","type":"cell"}],"outputs":[]},{"name":"acceptTransfer","id":"0x67A0B95F","inputs":[{"name":"amount","type":"uint128"},{"name":"sender","type":"address"},{"name":"remainingGasTo","type":"address"},{"name":"notify","type":"bool"},{"name":"payload","type":"cell"}],"outputs":[]},{"name":"acceptMint","id":"0x4384F298","inputs":[{"name":"amount","type":"uint128"},{"name":"remainingGasTo","type":"address"},{"name":"notify","type":"bool"},{"name":"payload","type":"cell"}],"outputs":[]},{"name":"sendSurplusGas","inputs":[{"name":"to","type":"address"}],"outputs":[]}],"data":[{"key":1,"name":"root_","type":"address"},{"key":2,"name":"owner_","type":"address"}],"events":[],"fields":[{"name":"_pubkey","type":"uint256"},{"name":"_timestamp","type":"uint64"},{"name":"_constructorFlag","type":"bool"},{"name":"root_","type":"address"},{"name":"owner_","type":"address"},{"name":"balance_","type":"uint128"},{"name":"version_","type":"uint32"},{"name":"platformCode_","type":"cell"}]} as const 6 | const vestingAbi = {"ABIversion":2,"version":"2.2","header":["time","expire"],"functions":[{"name":"constructor","inputs":[{"name":"_user","type":"address"},{"name":"_creator","type":"address"},{"name":"_remainingGasTo","type":"address"},{"name":"_token","type":"address"},{"name":"_vestingAmount","type":"uint128"},{"name":"_vestingStart","type":"uint32"},{"name":"_vestingEnd","type":"uint32"}],"outputs":[]},{"name":"receiveTokenWalletAddress","inputs":[{"name":"wallet","type":"address"}],"outputs":[]},{"name":"dummy","inputs":[{"name":"value0","type":"address"}],"outputs":[]},{"name":"getDetails","inputs":[],"outputs":[{"name":"_user","type":"address"},{"name":"_creator","type":"address"},{"name":"_token","type":"address"},{"name":"_vestingAmount","type":"uint128"},{"name":"_vestingStart","type":"uint32"},{"name":"_vestingEnd","type":"uint32"},{"name":"_lastClaimTime","type":"uint32"},{"name":"_tokenBalance","type":"uint128"},{"name":"_tokenWallet","type":"address"},{"name":"_filled","type":"bool"},{"name":"_vested","type":"bool"},{"name":"_nonce","type":"uint128"},{"name":"_factory","type":"address"}]},{"name":"onAcceptTokensTransfer","inputs":[{"name":"value0","type":"address"},{"name":"amount","type":"uint128"},{"name":"sender","type":"address"},{"name":"value3","type":"address"},{"name":"remainingGasTo","type":"address"},{"name":"value5","type":"cell"}],"outputs":[]},{"name":"pendingVested","inputs":[],"outputs":[{"name":"tokens_to_claim","type":"uint128"}]},{"name":"claim","inputs":[],"outputs":[]}],"data":[{"key":1,"name":"nonce","type":"uint128"},{"key":2,"name":"factory","type":"address"}],"events":[{"name":"ReceivedTokenWalletAddress","inputs":[{"name":"wallet","type":"address"}],"outputs":[]},{"name":"Deposit","inputs":[{"name":"sender","type":"address"},{"name":"amount","type":"uint128"}],"outputs":[]},{"name":"BadDeposit","inputs":[{"name":"sender","type":"address"},{"name":"amount","type":"uint128"}],"outputs":[]},{"name":"Claim","inputs":[{"name":"amount","type":"uint128"},{"name":"remaining_amount","type":"uint128"}],"outputs":[]},{"name":"Vested","inputs":[],"outputs":[]}],"fields":[{"name":"_pubkey","type":"uint256"},{"name":"_timestamp","type":"uint64"},{"name":"_constructorFlag","type":"bool"},{"name":"nonce","type":"uint128"},{"name":"factory","type":"address"},{"name":"user","type":"address"},{"name":"creator","type":"address"},{"name":"token","type":"address"},{"name":"vestingAmount","type":"uint128"},{"name":"vestingStart","type":"uint32"},{"name":"vestingEnd","type":"uint32"},{"name":"lastClaimTime","type":"uint32"},{"name":"tokenBalance","type":"uint128"},{"name":"tokenWallet","type":"address"},{"name":"filled","type":"bool"},{"name":"vested","type":"bool"}]} as const 7 | const vestingFactoryAbi = {"ABIversion":2,"version":"2.2","header":["pubkey","time","expire"],"functions":[{"name":"constructor","inputs":[{"name":"indexCode","type":"cell"},{"name":"indexDeployValue","type":"uint128"},{"name":"indexDestroyValue","type":"uint128"}],"outputs":[]},{"name":"deployNativeVesting","inputs":[{"name":"user","type":"address"},{"name":"remainingGasTo","type":"address"},{"name":"vesting_amount","type":"uint128"},{"name":"vesting_start","type":"uint32"},{"name":"vesting_end","type":"uint32"}],"outputs":[]},{"name":"deployVesting","inputs":[{"name":"user","type":"address"},{"name":"remainingGasTo","type":"address"},{"name":"token","type":"address"},{"name":"vesting_amount","type":"uint128"},{"name":"vesting_start","type":"uint32"},{"name":"vesting_end","type":"uint32"}],"outputs":[]},{"name":"onVestingDeployed","inputs":[{"name":"nonce","type":"uint128"},{"name":"user","type":"address"},{"name":"creator","type":"address"},{"name":"remainingGasTo","type":"address"},{"name":"token","type":"address"},{"name":"vesting_amount","type":"uint128"},{"name":"vesting_start","type":"uint32"},{"name":"vesting_end","type":"uint32"}],"outputs":[]},{"name":"getIndexCode","inputs":[{"name":"answerId","type":"uint32"}],"outputs":[{"name":"value0","type":"cell"}]},{"name":"resolveIndexCodeHash","inputs":[{"name":"answerId","type":"uint32"},{"name":"saltKey","type":"string"},{"name":"saltValue","type":"cell"}],"outputs":[{"name":"value0","type":"uint256"}]},{"name":"deploy_nonce","inputs":[],"outputs":[{"name":"deploy_nonce","type":"uint128"}]},{"name":"vestings_deployed","inputs":[],"outputs":[{"name":"vestings_deployed","type":"uint128"}]}],"data":[{"key":1,"name":"deploy_nonce","type":"uint128"},{"key":2,"name":"vestingCode","type":"cell"},{"key":3,"name":"nativeVestingCode","type":"cell"}],"events":[{"name":"NewVesting","inputs":[{"name":"vesting","type":"address"},{"name":"user","type":"address"},{"name":"creator","type":"address"},{"name":"token","type":"address"},{"name":"amount","type":"uint128"},{"name":"start","type":"uint32"},{"name":"end","type":"uint32"}],"outputs":[]},{"name":"IndexDeployed","inputs":[{"name":"index","type":"address"},{"name":"indexedContract","type":"address"},{"name":"indexCodeHash","type":"uint256"},{"name":"saltKey","type":"string"},{"name":"saltValue","type":"cell"}],"outputs":[]}],"fields":[{"name":"_pubkey","type":"uint256"},{"name":"_timestamp","type":"uint64"},{"name":"_constructorFlag","type":"bool"},{"name":"_indexDeployValue","type":"uint128"},{"name":"_indexDestroyValue","type":"uint128"},{"name":"_indexCode","type":"cell"},{"name":"deploy_nonce","type":"uint128"},{"name":"vestingCode","type":"cell"},{"name":"nativeVestingCode","type":"cell"},{"name":"vestings_deployed","type":"uint128"}]} as const 8 | const walletAbi = {"ABIversion":2,"version":"2.2","header":["pubkey","time","expire"],"functions":[{"name":"sendTransaction","inputs":[{"name":"dest","type":"address"},{"name":"value","type":"uint128"},{"name":"bounce","type":"bool"},{"name":"flags","type":"uint8"},{"name":"payload","type":"cell"}],"outputs":[]},{"name":"transferOwnership","inputs":[{"name":"newOwner","type":"uint256"}],"outputs":[]},{"name":"constructor","inputs":[],"outputs":[]},{"name":"owner","inputs":[],"outputs":[{"name":"owner","type":"uint256"}]},{"name":"_randomNonce","inputs":[],"outputs":[{"name":"_randomNonce","type":"uint256"}]}],"data":[{"key":1,"name":"_randomNonce","type":"uint256"}],"events":[{"name":"OwnershipTransferred","inputs":[{"name":"previousOwner","type":"uint256"},{"name":"newOwner","type":"uint256"}],"outputs":[]}],"fields":[{"name":"_pubkey","type":"uint256"},{"name":"_timestamp","type":"uint64"},{"name":"_constructorFlag","type":"bool"},{"name":"owner","type":"uint256"},{"name":"_randomNonce","type":"uint256"}]} as const 9 | 10 | export const factorySource = { 11 | Index: indexAbi, 12 | NativeVesting: nativeVestingAbi, 13 | TokenRootUpgradeable: tokenRootUpgradeableAbi, 14 | TokenWalletPlatform: tokenWalletPlatformAbi, 15 | TokenWalletUpgradeable: tokenWalletUpgradeableAbi, 16 | Vesting: vestingAbi, 17 | VestingFactory: vestingFactoryAbi, 18 | Wallet: walletAbi 19 | } as const 20 | 21 | export type FactorySource = typeof factorySource 22 | export type IndexAbi = typeof indexAbi 23 | export type NativeVestingAbi = typeof nativeVestingAbi 24 | export type TokenRootUpgradeableAbi = typeof tokenRootUpgradeableAbi 25 | export type TokenWalletPlatformAbi = typeof tokenWalletPlatformAbi 26 | export type TokenWalletUpgradeableAbi = typeof tokenWalletUpgradeableAbi 27 | export type VestingAbi = typeof vestingAbi 28 | export type VestingFactoryAbi = typeof vestingFactoryAbi 29 | export type WalletAbi = typeof walletAbi 30 | -------------------------------------------------------------------------------- /contracts/NativeVesting.sol: -------------------------------------------------------------------------------- 1 | pragma ever-solidity ^0.62.0; 2 | pragma AbiHeader expire; 3 | 4 | import "@broxus/contracts/contracts/libraries/MsgFlag.tsol"; 5 | import "interfaces/IFactory.sol"; 6 | 7 | contract NativeVesting { 8 | event Deposit(address sender, uint128 amount); 9 | event Claim(uint128 amount, uint128 remaining_amount); 10 | event Vested(); 11 | 12 | uint128 static nonce; 13 | address static factory; 14 | 15 | // setup params 16 | address user; 17 | address creator; 18 | uint128 vestingAmount; 19 | uint32 vestingStart; 20 | uint32 vestingEnd; 21 | 22 | uint32 lastClaimTime; 23 | uint128 balance; 24 | bool filled; 25 | bool vested; 26 | 27 | uint16 constant NOT_USER = 1001; 28 | uint16 constant NOT_FACTORY = 1002; 29 | uint16 constant FILLED_ALREDY = 1003; 30 | uint16 constant NOT_STARTED = 1004; 31 | uint16 constant NOT_FILLED = 1005; 32 | uint16 constant VESTED_ALREADY = 1006; 33 | uint16 constant LOW_VALUE = 1007; 34 | 35 | uint128 constant CONTRACT_MIN_BALANCE = 1 ton; 36 | uint128 constant MIN_MSG_VALUE = 1 ton; 37 | 38 | constructor( 39 | address _user, 40 | address _creator, 41 | address _remainingGasTo, 42 | uint128 _vestingAmount, 43 | uint32 _vestingStart, 44 | uint32 _vestingEnd 45 | ) public { 46 | require(msg.sender == factory, NOT_FACTORY); 47 | tvm.rawReserve(CONTRACT_MIN_BALANCE, 0); 48 | 49 | user = _user; 50 | creator = _creator; 51 | vestingAmount = _vestingAmount; 52 | vestingStart = _vestingStart; 53 | vestingEnd = _vestingEnd; 54 | lastClaimTime = vestingStart; 55 | 56 | IFactory(factory).onVestingDeployed{ 57 | value: 0, 58 | flag: MsgFlag.ALL_NOT_RESERVED 59 | }( 60 | nonce, 61 | user, 62 | creator, 63 | _remainingGasTo, 64 | address.makeAddrNone(), 65 | vestingAmount, 66 | vestingStart, 67 | vestingEnd 68 | ); 69 | } 70 | 71 | function getDetails() 72 | external 73 | view 74 | returns ( 75 | address _user, 76 | address _creator, 77 | uint128 _vestingAmount, 78 | uint32 _vestingStart, 79 | uint32 _vestingEnd, 80 | uint32 _lastClaimTime, 81 | uint128 _balance, 82 | bool _filled, 83 | bool _vested, 84 | uint128 _nonce, 85 | address _factory 86 | ) 87 | { 88 | return ( 89 | user, 90 | creator, 91 | vestingAmount, 92 | vestingStart, 93 | vestingEnd, 94 | lastClaimTime, 95 | balance, 96 | filled, 97 | vested, 98 | nonce, 99 | factory 100 | ); 101 | } 102 | 103 | function deposit(address send_gas_to) external { 104 | require(msg.value >= vestingAmount + MIN_MSG_VALUE, LOW_VALUE); 105 | require(filled == false, FILLED_ALREDY); 106 | 107 | balance = vestingAmount; 108 | filled = true; 109 | 110 | emit Deposit(msg.sender, vestingAmount); 111 | tvm.rawReserve(vestingAmount + CONTRACT_MIN_BALANCE, 0); 112 | 113 | send_gas_to.transfer(0, false, MsgFlag.ALL_NOT_RESERVED); 114 | } 115 | 116 | function pendingVested() external view returns (uint128 value_to_claim) { 117 | if (now >= vestingEnd) { 118 | value_to_claim = balance; 119 | } else if (now >= lastClaimTime) { 120 | uint32 period_left = vestingEnd - lastClaimTime; 121 | uint32 period_passed = now - lastClaimTime; 122 | value_to_claim = (balance * period_passed) / period_left; 123 | } 124 | } 125 | 126 | function claim() external { 127 | require(msg.sender == user, NOT_USER); 128 | require(now >= vestingStart, NOT_STARTED); 129 | require(filled == true, NOT_FILLED); 130 | require(vested == false, VESTED_ALREADY); 131 | require(msg.value >= MIN_MSG_VALUE, LOW_VALUE); 132 | 133 | uint128 value_to_claim; 134 | if (now >= vestingEnd) { 135 | value_to_claim = balance; 136 | } else { 137 | uint32 period_left = vestingEnd - lastClaimTime; 138 | uint32 period_passed = now - lastClaimTime; 139 | value_to_claim = (balance * period_passed) / period_left; 140 | } 141 | 142 | balance -= value_to_claim; 143 | lastClaimTime = now; 144 | 145 | emit Claim(value_to_claim, balance); 146 | if (balance == 0) { 147 | vested = true; 148 | emit Vested(); 149 | } 150 | 151 | tvm.rawReserve(balance + CONTRACT_MIN_BALANCE, 0); 152 | msg.sender.transfer(0, false, MsgFlag.ALL_NOT_RESERVED); 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /contracts/Vesting.sol: -------------------------------------------------------------------------------- 1 | pragma ever-solidity ^0.62.0; 2 | pragma AbiHeader expire; 3 | 4 | import "broxus-token-contracts/contracts/interfaces/ITokenRoot.tsol"; 5 | import "broxus-token-contracts/contracts/interfaces/ITokenWallet.tsol"; 6 | import "broxus-token-contracts/contracts/interfaces/IAcceptTokensTransferCallback.tsol"; 7 | import "@broxus/contracts/contracts/libraries/MsgFlag.tsol"; 8 | import "interfaces/IFactory.sol"; 9 | 10 | contract Vesting { 11 | event ReceivedTokenWalletAddress(address wallet); 12 | event Deposit(address sender, uint128 amount); 13 | event BadDeposit(address sender, uint128 amount); 14 | event Claim(uint128 amount, uint128 remaining_amount); 15 | event Vested(); 16 | 17 | uint128 static nonce; 18 | address static factory; 19 | 20 | // setup params 21 | address user; 22 | address creator; 23 | address token; 24 | uint128 vestingAmount; 25 | uint32 vestingStart; 26 | uint32 vestingEnd; 27 | 28 | uint32 lastClaimTime; 29 | uint128 tokenBalance; 30 | address tokenWallet; 31 | bool filled; 32 | bool vested; 33 | 34 | uint16 constant NOT_USER = 1001; 35 | uint16 constant NOT_FACTORY = 1002; 36 | uint16 constant NOT_WALLET = 1003; 37 | uint16 constant NOT_STARTED = 1004; 38 | uint16 constant NOT_FILLED = 1005; 39 | uint16 constant VESTED_ALREADY = 1006; 40 | uint16 constant LOW_VALUE = 1007; 41 | uint16 constant NOT_TOKEN = 1008; 42 | 43 | uint128 constant TOKEN_WALLET_DEPLOY_VALUE = 0.5 ton; 44 | uint128 constant CONTRACT_MIN_BALANCE = 1 ton; 45 | uint128 constant MIN_MSG_VALUE = 1 ton; 46 | 47 | constructor( 48 | address _user, 49 | address _creator, 50 | address _remainingGasTo, 51 | address _token, 52 | uint128 _vestingAmount, 53 | uint32 _vestingStart, 54 | uint32 _vestingEnd 55 | ) public { 56 | require(msg.sender == factory, NOT_FACTORY); 57 | tvm.rawReserve(_reserve(), 0); 58 | 59 | user = _user; 60 | creator = _creator; 61 | token = _token; 62 | vestingAmount = _vestingAmount; 63 | vestingStart = _vestingStart; 64 | vestingEnd = _vestingEnd; 65 | lastClaimTime = vestingStart; 66 | 67 | _setupTokenWallets(); 68 | 69 | IFactory(factory).onVestingDeployed{ 70 | value: 0, 71 | flag: MsgFlag.ALL_NOT_RESERVED 72 | }( 73 | nonce, 74 | user, 75 | creator, 76 | _remainingGasTo, 77 | token, 78 | vestingAmount, 79 | vestingStart, 80 | vestingEnd 81 | ); 82 | } 83 | 84 | function _setupTokenWallets() internal view { 85 | ITokenRoot(token).deployWallet{ 86 | flag: 0, 87 | value: TOKEN_WALLET_DEPLOY_VALUE, 88 | callback: Vesting.receiveTokenWalletAddress 89 | }( 90 | address(this), // owner 91 | TOKEN_WALLET_DEPLOY_VALUE / 2 // deploy grams 92 | ); 93 | 94 | ITokenRoot(token).deployWallet{ 95 | flag: 0, 96 | value: TOKEN_WALLET_DEPLOY_VALUE, 97 | callback: Vesting.dummy 98 | }( 99 | user, // owner 100 | TOKEN_WALLET_DEPLOY_VALUE / 2 // deploy grams 101 | ); 102 | } 103 | 104 | function receiveTokenWalletAddress(address wallet) external { 105 | require(msg.sender == token, NOT_TOKEN); 106 | tokenWallet = wallet; 107 | emit ReceivedTokenWalletAddress(wallet); 108 | } 109 | 110 | function dummy(address) external view { 111 | require(msg.sender == token, NOT_TOKEN); 112 | } 113 | 114 | function getDetails() 115 | external 116 | view 117 | returns ( 118 | address _user, 119 | address _creator, 120 | address _token, 121 | uint128 _vestingAmount, 122 | uint32 _vestingStart, 123 | uint32 _vestingEnd, 124 | uint32 _lastClaimTime, 125 | uint128 _tokenBalance, 126 | address _tokenWallet, 127 | bool _filled, 128 | bool _vested, 129 | uint128 _nonce, 130 | address _factory 131 | ) 132 | { 133 | return ( 134 | user, 135 | creator, 136 | token, 137 | vestingAmount, 138 | vestingStart, 139 | vestingEnd, 140 | lastClaimTime, 141 | tokenBalance, 142 | tokenWallet, 143 | filled, 144 | vested, 145 | nonce, 146 | factory 147 | ); 148 | } 149 | 150 | function _reserve() internal pure virtual returns (uint128) { 151 | return 152 | math.max(address(this).balance - msg.value, CONTRACT_MIN_BALANCE); 153 | } 154 | 155 | // deposit occurs here 156 | function onAcceptTokensTransfer( 157 | address, 158 | uint128 amount, 159 | address sender, 160 | address, 161 | address remainingGasTo, 162 | TvmCell 163 | ) external { 164 | require(msg.sender == tokenWallet, NOT_WALLET); 165 | 166 | tvm.rawReserve(_reserve(), 0); 167 | 168 | if (amount != vestingAmount || filled == true) { 169 | emit BadDeposit(sender, amount); 170 | TvmCell empty; 171 | ITokenWallet(tokenWallet).transfer{ 172 | value: 0, 173 | flag: MsgFlag.ALL_NOT_RESERVED 174 | }(amount, sender, 0, sender, false, empty); 175 | return; 176 | } 177 | 178 | tokenBalance = amount; 179 | filled = true; 180 | 181 | emit Deposit(sender, amount); 182 | remainingGasTo.transfer(0, false, MsgFlag.ALL_NOT_RESERVED); 183 | } 184 | 185 | function pendingVested() external view returns (uint128 tokens_to_claim) { 186 | if (now >= vestingEnd) { 187 | tokens_to_claim = tokenBalance; 188 | } else if (now >= lastClaimTime) { 189 | uint32 period_left = vestingEnd - lastClaimTime; 190 | uint32 period_passed = now - lastClaimTime; 191 | tokens_to_claim = (tokenBalance * period_passed) / period_left; 192 | } 193 | } 194 | 195 | function claim() external { 196 | require(msg.sender == user, NOT_USER); 197 | require(now >= vestingStart, NOT_STARTED); 198 | require(filled == true, NOT_FILLED); 199 | require(vested == false, VESTED_ALREADY); 200 | require(msg.value >= MIN_MSG_VALUE, LOW_VALUE); 201 | 202 | tvm.rawReserve(_reserve(), 0); 203 | 204 | uint128 tokens_to_claim; 205 | if (now >= vestingEnd) { 206 | tokens_to_claim = tokenBalance; 207 | } else { 208 | uint32 period_left = vestingEnd - lastClaimTime; 209 | uint32 period_passed = now - lastClaimTime; 210 | tokens_to_claim = (tokenBalance * period_passed) / period_left; 211 | } 212 | 213 | tokenBalance -= tokens_to_claim; 214 | lastClaimTime = now; 215 | 216 | emit Claim(tokens_to_claim, tokenBalance); 217 | if (tokenBalance == 0) { 218 | vested = true; 219 | emit Vested(); 220 | } 221 | 222 | TvmCell empty; 223 | ITokenWallet(tokenWallet).transfer{ 224 | value: 0, 225 | flag: MsgFlag.ALL_NOT_RESERVED 226 | }(tokens_to_claim, user, 0, user, false, empty); 227 | } 228 | } 229 | -------------------------------------------------------------------------------- /contracts/VestingFactory.sol: -------------------------------------------------------------------------------- 1 | pragma ever-solidity ^0.62.0; 2 | pragma AbiHeader expire; 3 | pragma AbiHeader pubkey; 4 | 5 | import "@broxus/contracts/contracts/libraries/MsgFlag.tsol"; 6 | import "Vesting.sol"; 7 | import "NativeVesting.sol"; 8 | import "indexer/IndexFactory.tsol"; 9 | 10 | contract VestingFactory is IndexFactory { 11 | event NewVesting( 12 | address vesting, 13 | address user, 14 | address creator, 15 | address token, 16 | uint128 amount, 17 | uint32 start, 18 | uint32 end 19 | ); 20 | 21 | uint128 public static deploy_nonce; 22 | TvmCell static vestingCode; 23 | TvmCell static nativeVestingCode; 24 | uint128 public vestings_deployed; 25 | 26 | uint16 constant WRONG_PUBKEY = 1001; 27 | uint16 constant BAD_PARAMS = 1002; 28 | uint16 constant LOW_VALUE = 1003; 29 | uint16 constant NOT_VESTING = 1004; 30 | 31 | uint128 constant CONTRACT_MIN_BALANCE = 1 ton; 32 | uint128 constant VESTING_DEPLOY_VALUE = 2 ton; 33 | 34 | constructor( 35 | TvmCell indexCode, 36 | uint128 indexDeployValue, 37 | uint128 indexDestroyValue 38 | ) public IndexFactory(indexCode, indexDeployValue, indexDestroyValue) { 39 | require(tvm.pubkey() != 0, WRONG_PUBKEY); 40 | require(tvm.pubkey() == msg.pubkey(), WRONG_PUBKEY); 41 | tvm.accept(); 42 | } 43 | 44 | function _reserve() internal pure returns (uint128) { 45 | return 46 | math.max(address(this).balance - msg.value, CONTRACT_MIN_BALANCE); 47 | } 48 | 49 | function deployNativeVesting( 50 | address user, 51 | address remainingGasTo, 52 | uint128 vesting_amount, 53 | uint32 vesting_start, 54 | uint32 vesting_end 55 | ) external { 56 | require(vesting_start > now, BAD_PARAMS); 57 | require(vesting_end > vesting_start, BAD_PARAMS); 58 | require(vesting_amount > 0, BAD_PARAMS); 59 | require( 60 | msg.value >= VESTING_DEPLOY_VALUE + _indexDeployValue * 2, 61 | LOW_VALUE 62 | ); 63 | tvm.rawReserve(_reserve(), 0); 64 | 65 | TvmCell stateInit = tvm.buildStateInit({ 66 | contr: NativeVesting, 67 | varInit: { nonce: vestings_deployed, factory: address(this) }, 68 | pubkey: tvm.pubkey(), 69 | code: nativeVestingCode 70 | }); 71 | vestings_deployed += 1; 72 | 73 | new NativeVesting{ 74 | stateInit: stateInit, 75 | value: 0, 76 | wid: address(this).wid, 77 | flag: MsgFlag.ALL_NOT_RESERVED 78 | }( 79 | user, 80 | msg.sender, 81 | remainingGasTo, 82 | vesting_amount, 83 | vesting_start, 84 | vesting_end 85 | ); 86 | } 87 | 88 | function deployVesting( 89 | address user, 90 | address remainingGasTo, 91 | address token, 92 | uint128 vesting_amount, 93 | uint32 vesting_start, 94 | uint32 vesting_end 95 | ) external { 96 | require(vesting_start > now, BAD_PARAMS); 97 | require(vesting_end > vesting_start, BAD_PARAMS); 98 | require(vesting_amount > 0, BAD_PARAMS); 99 | require( 100 | msg.value >= VESTING_DEPLOY_VALUE + _indexDeployValue * 3, 101 | LOW_VALUE 102 | ); 103 | tvm.rawReserve(_reserve(), 0); 104 | 105 | TvmCell stateInit = tvm.buildStateInit({ 106 | contr: Vesting, 107 | varInit: { nonce: vestings_deployed, factory: address(this) }, 108 | pubkey: tvm.pubkey(), 109 | code: vestingCode 110 | }); 111 | vestings_deployed += 1; 112 | 113 | new Vesting{ 114 | stateInit: stateInit, 115 | value: 0, 116 | wid: address(this).wid, 117 | flag: MsgFlag.ALL_NOT_RESERVED 118 | }( 119 | user, 120 | msg.sender, 121 | remainingGasTo, 122 | token, 123 | vesting_amount, 124 | vesting_start, 125 | vesting_end 126 | ); 127 | } 128 | 129 | function onVestingDeployed( 130 | uint128 nonce, 131 | address user, 132 | address creator, 133 | address remainingGasTo, 134 | address token, 135 | uint128 vesting_amount, 136 | uint32 vesting_start, 137 | uint32 vesting_end 138 | ) external view { 139 | tvm.rawReserve(_reserve(), 0); 140 | TvmCell stateInit; 141 | string vesting_contract_type = "Vesting"; 142 | if (token == address.makeAddrNone()) { 143 | vesting_contract_type = "NativeVesting"; 144 | stateInit = tvm.buildStateInit({ 145 | contr: NativeVesting, 146 | varInit: { nonce: nonce, factory: address(this) }, 147 | pubkey: tvm.pubkey(), 148 | code: nativeVestingCode 149 | }); 150 | } else { 151 | stateInit = tvm.buildStateInit({ 152 | contr: Vesting, 153 | varInit: { nonce: nonce, factory: address(this) }, 154 | pubkey: tvm.pubkey(), 155 | code: vestingCode 156 | }); 157 | } 158 | 159 | address vesting_address = address(tvm.hash(stateInit)); 160 | require(msg.sender == vesting_address, NOT_VESTING); 161 | 162 | emit NewVesting( 163 | msg.sender, 164 | user, 165 | creator, 166 | token, 167 | vesting_amount, 168 | vesting_start, 169 | vesting_end 170 | ); 171 | 172 | deployUserIndex( 173 | vesting_address, 174 | "recipient", 175 | user, 176 | vesting_contract_type 177 | ); 178 | 179 | deployUserIndex( 180 | vesting_address, 181 | "creator", 182 | creator, 183 | vesting_contract_type 184 | ); 185 | if (vesting_contract_type == "Vesting") { 186 | deployTokenIndex(vesting_address, "token", token); 187 | } 188 | 189 | remainingGasTo.transfer({ value: 0, flag: MsgFlag.ALL_NOT_RESERVED }); 190 | } 191 | 192 | function deployUserIndex( 193 | address vesting, 194 | string indexName, 195 | address user, 196 | string contractType 197 | ) internal view { 198 | TvmBuilder builder; 199 | builder.store(user); 200 | builder.store(contractType); 201 | deployIndex(vesting, indexName, builder.toCell()); 202 | } 203 | 204 | function deployTokenIndex( 205 | address vesting, 206 | string indexName, 207 | address token 208 | ) internal view { 209 | TvmBuilder builder; 210 | builder.store(token); 211 | deployIndex(vesting, indexName, builder.toCell()); 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /contracts/indexer/Index.tsol: -------------------------------------------------------------------------------- 1 | pragma ever-solidity ^0.62.0; 2 | 3 | pragma AbiHeader expire; 4 | pragma AbiHeader pubkey; 5 | 6 | /** 7 | * Errors 8 | * 1001 - Salt doesn't contain any value 9 | * 1002 - Method for IndexFactory only 10 | **/ 11 | 12 | contract Index { 13 | // Address of the indexed contract 14 | address static _indexedContract; 15 | // Hash of the parameters used to salt the contract 16 | uint256 static _saltHash; 17 | 18 | // Address of the IndexFactory contract 19 | address _indexFactory; 20 | 21 | constructor() public { 22 | optional(TvmCell) salt = tvm.codeSalt(tvm.code()); 23 | require(salt.hasValue(), 1001, "Salt doesn't contain any value"); 24 | address indexFactory = salt.get().toSlice().decode(address); 25 | require(msg.sender == indexFactory, 1002, "Method for IndexFactory only"); 26 | tvm.accept(); 27 | _indexFactory = indexFactory; 28 | } 29 | 30 | /** 31 | * @notice Get indexed contract 32 | * @return address of the indexed contract 33 | */ 34 | function getIndexedContract() public view responsible returns (address) { 35 | return { value: 0, bounce: false, flag: 64 } (_indexedContract); 36 | } 37 | 38 | /** 39 | * @notice Get IndexFactory address 40 | * @return address of the IndexFactory contract 41 | */ 42 | function getIndexFactory() public view responsible returns (address) { 43 | return { value: 0, bounce: false, flag: 64 } (_indexFactory); 44 | } 45 | 46 | /** 47 | * @notice Get code hash 48 | * @return hash of the code 49 | */ 50 | function getCodeHash() public pure responsible returns (uint256) { 51 | return { value: 0, bounce: false, flag: 64 } tvm.hash(tvm.code()); 52 | } 53 | 54 | /** 55 | * @notice Destruct the contract 56 | * @param gasReceiver Address to receive leftover gas from the destructed contract 57 | */ 58 | function destruct(address gasReceiver) public { 59 | require(msg.sender == _indexFactory, 1002, "Method for IndexFactory only"); 60 | selfdestruct(gasReceiver); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /contracts/indexer/IndexFactory.tsol: -------------------------------------------------------------------------------- 1 | pragma ever-solidity ^0.62.0; 2 | 3 | pragma AbiHeader expire; 4 | pragma AbiHeader pubkey; 5 | 6 | import "Index.tsol"; 7 | 8 | abstract contract IndexFactory { 9 | // Parameters to deploy/destroy Index contract 10 | uint128 _indexDeployValue; 11 | uint128 _indexDestroyValue; 12 | 13 | // variables 14 | TvmCell _indexCode; 15 | 16 | /** 17 | * @notice This event emits when Index is deployed 18 | * @param index Index address 19 | * @param indexedContract Indexed contract address 20 | * @param indexCodeHash Hash of the Index code, that can be used to find Indexes with the same parameters 21 | * @param saltKey The name of the salt parameters 22 | * @param saltValue Parameters of the salt packed into cell 23 | */ 24 | event IndexDeployed(address index, address indexedContract, uint256 indexCodeHash, string saltKey, TvmCell saltValue); 25 | 26 | constructor(TvmCell indexCode, uint128 indexDeployValue, uint128 indexDestroyValue) public { 27 | tvm.accept(); 28 | _indexCode = indexCode; 29 | _indexDeployValue = indexDeployValue; 30 | _indexDestroyValue = indexDestroyValue; 31 | } 32 | 33 | /** 34 | * @notice Returns the code of the Index contract 35 | * @return TvmCell representing the index code of the contract 36 | */ 37 | function getIndexCode() public view responsible returns (TvmCell) { 38 | return { value: 0, flag: 64, bounce: false } _indexCode; 39 | } 40 | 41 | /** 42 | * @notice Calculates and returns the code hash of the Index contract based on the provided salt parameters 43 | * @param saltKey The name of the salt parameters 44 | * @param saltValue Parameters of the salt packed into cell 45 | * @return The calculated code hash for the Index contract 46 | */ 47 | function resolveIndexCodeHash(string saltKey, TvmCell saltValue) public view responsible returns (uint256) { 48 | TvmCell salt = _buildSalt(saltKey, saltValue); 49 | TvmCell code = _buildIndexCode(salt); 50 | return { value: 0, flag: 64, bounce: false } tvm.hash(code); 51 | } 52 | 53 | /** 54 | * @notice Destroys a specified Index contract and sends its remaining gas to a specified address 55 | * @param index The address of the Index contract to be destroyed 56 | * @param sendGasTo The address to which the remaining gas of the Index contract will be sent 57 | */ 58 | function destructIndex(address index, address sendGasTo) internal view virtual { 59 | Index(index).destruct{ value: _indexDestroyValue, flag: 0 }(sendGasTo); 60 | } 61 | 62 | /** 63 | * @notice Deploys a new Index contract with given indexedContract address and salt parameters 64 | * @param indexedContract Indexed contract address 65 | * @param saltKey The name of the salt parameters 66 | * @param saltValue Parameters of the salt packed into cell 67 | */ 68 | function deployIndex(address indexedContract, string saltKey, TvmCell saltValue) internal view { 69 | TvmCell salt = _buildSalt(saltKey, saltValue); 70 | TvmCell indexCode = _buildIndexCode(salt); 71 | TvmCell indexState = _buildIndexState(indexCode, tvm.hash(salt), indexedContract); 72 | 73 | new Index{ stateInit: indexState, value: _indexDeployValue, flag: 1 }(); 74 | emit IndexDeployed(address(tvm.hash(indexState)), indexedContract, tvm.hash(indexCode), saltKey, saltValue); 75 | } 76 | 77 | /** 78 | * @notice Builds a TvmCell using the provided salt parameters. 79 | * @param saltKey The name of the salt parameters 80 | * @param saltValue Parameters of the salt packed into cell 81 | * @return TvmCell built using the provided salt parameters. 82 | */ 83 | function _buildSalt(string saltKey, TvmCell saltValue) internal pure returns (TvmCell) { 84 | TvmBuilder salt; 85 | // salt with index factory address 86 | salt.store(address(this)); 87 | // salt with salt key 88 | salt.store(saltKey); 89 | // salt with salt value 90 | salt.store(saltValue); 91 | 92 | return salt.toCell(); 93 | } 94 | 95 | /** 96 | * @notice Builds the Index contract code using the provided salt. 97 | * @param salt TvmCell salt used to build the Index contract code. 98 | * @return TvmCell representing the Index contract code. 99 | */ 100 | function _buildIndexCode(TvmCell salt) internal view returns (TvmCell) { 101 | return tvm.setCodeSalt(_indexCode, salt); 102 | } 103 | 104 | /** 105 | * @notice Builds the state for the Index contract using the provided code and salt parameters. 106 | * @param code TvmCell representing the Index contract code. 107 | * @param saltHash uint256 Salt hash to uniqalize the Index contract state (and address). 108 | * @param indexedContract Address of the indexed contract. 109 | * @return TvmCell representing the Index contract state. 110 | */ 111 | function _buildIndexState(TvmCell code, uint256 saltHash, address indexedContract) internal pure returns (TvmCell) { 112 | return 113 | tvm.buildStateInit({ 114 | contr: Index, 115 | varInit: { _saltHash: saltHash, _indexedContract: indexedContract }, 116 | code: code 117 | }); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /contracts/interfaces/IFactory.sol: -------------------------------------------------------------------------------- 1 | pragma ever-solidity ^0.62.0; 2 | 3 | interface IFactory { 4 | function onVestingDeployed( 5 | uint128 nonce, 6 | address user, 7 | address creator, 8 | address remainingGasTo, 9 | address token, 10 | uint128 vesting_amount, 11 | uint32 vesting_start, 12 | uint32 vesting_end 13 | ) external; 14 | } 15 | -------------------------------------------------------------------------------- /locklift.config.ts: -------------------------------------------------------------------------------- 1 | import { LockliftConfig } from "locklift"; 2 | 3 | import { FactorySource } from "./build/factorySource"; 4 | 5 | import { DeployArtifactsExtension } from "locklift-deploy-artifacts"; 6 | import { LockliftConfigExtension, PrivateDeployerExtension } from "locklift-private-deploy"; 7 | import "locklift-deploy-artifacts"; 8 | import "locklift-private-deploy"; 9 | 10 | declare module "locklift" { 11 | export interface Locklift 12 | extends DeployArtifactsExtension, 13 | PrivateDeployerExtension {} 14 | export interface LockliftConfig extends LockliftConfigExtension {} 15 | } 16 | declare global { 17 | const locklift: import("locklift").Locklift; 18 | } 19 | 20 | const LOCAL_NETWORK_ENDPOINT = "http://localhost/graphql"; 21 | 22 | const VENOM_TESTNET_ENDPOINT = process.env.VENOM_TESTNET_ENDPOINT || "https://jrpc-testnet.venom.foundation/rpc"; 23 | const VENOM_TESTNET_TRACE_ENDPOINT = 24 | process.env.VENOM_TESTNET_TRACE_ENDPOINT || "https://gql-testnet.venom.foundation/graphql"; 25 | 26 | const config: LockliftConfig = { 27 | pivateRPC: "", 28 | compiler: { 29 | // Specify path to your TON-Solidity-Compiler 30 | // path: "/mnt/o/projects/broxus/TON-Solidity-Compiler/build/solc/solc", 31 | 32 | // Or specify version of compiler 33 | version: "0.62.0", 34 | 35 | // Specify config for extarnal contracts as in exapmple 36 | externalContracts: { 37 | "node_modules/broxus-token-contracts/build": [ 38 | "TokenRootUpgradeable", 39 | "TokenWalletUpgradeable", 40 | "TokenWalletPlatform", 41 | ], 42 | "test/contracts/build": ["Wallet"], 43 | }, 44 | }, 45 | linker: { 46 | // Specify path to your stdlib 47 | // lib: "/mnt/o/projects/broxus/TON-Solidity-Compiler/lib/stdlib_sol.tvm", 48 | // // Specify path to your Linker 49 | // path: "/mnt/o/projects/broxus/TVM-linker/target/release/tvm_linker", 50 | 51 | // Or specify version of linker 52 | version: "0.15.48", 53 | }, 54 | networks: { 55 | local: { 56 | // Specify connection settings for https://github.com/broxus/everscale-standalone-client/ 57 | connection: { 58 | id: 1, 59 | group: "localnet", 60 | type: "graphql", 61 | data: { 62 | endpoints: [LOCAL_NETWORK_ENDPOINT], 63 | latencyDetectionInterval: 1000, 64 | local: true, 65 | }, 66 | }, 67 | // This giver is default local-node giverV2 68 | giver: { 69 | // Check if you need provide custom giver 70 | address: "0:ece57bcc6c530283becbbd8a3b24d3c5987cdddc3c8b7b33be6e4a6312490415", 71 | key: "172af540e43a524763dd53b26a066d472a97c4de37d5498170564510608250c3", 72 | }, 73 | tracing: { 74 | endpoint: LOCAL_NETWORK_ENDPOINT, 75 | }, 76 | keys: { 77 | // Use everdev to generate your phrase 78 | // !!! Never commit it in your repos !!! 79 | // phrase: "action inject penalty envelope rabbit element slim tornado dinner pizza off blood", 80 | amount: 20, 81 | }, 82 | }, 83 | // test: { 84 | // connection: { 85 | // id: 1000, 86 | // type: "jrpc", 87 | // group: "dev", 88 | // data: { 89 | // endpoint: VENOM_TESTNET_ENDPOINT, 90 | // }, 91 | // }, 92 | // giver: { 93 | // address: "", 94 | // key: "", 95 | // }, 96 | // tracing: { 97 | // endpoint: VENOM_TESTNET_TRACE_ENDPOINT, 98 | // }, 99 | // keys: { 100 | // // Use everdev to generate your phrase 101 | // // !!! Never commit it in your repos !!! 102 | // phrase: "", 103 | // amount: 20, 104 | // }, 105 | // }, 106 | }, 107 | mocha: { 108 | timeout: 2000000, 109 | }, 110 | }; 111 | 112 | export default config; 113 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "qube-dao-contracts", 3 | "version": "1.0.0", 4 | "description": "", 5 | "author": "30mb1 ", 6 | "license": "ISC", 7 | "scripts": { 8 | "run:local-node": "docker run --rm -d --name local-node -e USER_AGREEMENT=yes -p 80:80 tonlabs/local-node", 9 | "stop:local-node": "docker stop local-node" 10 | }, 11 | "dependencies": { 12 | "@broxus/contracts": "^1.0.4", 13 | "@eversdk/ton": "^0.1.1", 14 | "broxus-token-contracts": "github:broxus/tip3#480c1b4481d1dddb028b408b20ba8c19abd1a4a4", 15 | "nekoton-wasm": "^1.1.7" 16 | }, 17 | "devDependencies": { 18 | "@types/chai": "^4.3.3", 19 | "@types/mocha": "^9.1.1", 20 | "@types/node": "^18.7.6", 21 | "chai": "^4.3.6", 22 | "locklift": "~2.5.5", 23 | "locklift-deploy-artifacts": "^1.1.1", 24 | "locklift-private-deploy": "^1.0.6", 25 | "prettier": "^2.7.1", 26 | "ts-mocha": "^10.0.0", 27 | "typescript": "^4.7.4" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /script/1-deploy-factory.ts: -------------------------------------------------------------------------------- 1 | async function main() { 2 | console.log(`Deploying VestingFactory...`); 3 | const signer = (await locklift.keystore.getSigner("0"))!; 4 | 5 | const indexArtifacts = locklift.factory.getContractArtifacts("Index"); 6 | const vestingArtifacts = locklift.factory.getContractArtifacts("Vesting"); 7 | const nativeVestingArtifacts = 8 | locklift.factory.getContractArtifacts("NativeVesting"); 9 | 10 | const { contract: vestingFactory } = 11 | await locklift.deployArtifacts.deployContract( 12 | "VestingFactory", 13 | "latest", 14 | { 15 | contract: "VestingFactory", 16 | publicKey: signer?.publicKey as string, 17 | initParams: { 18 | deploy_nonce: locklift.utils.getRandomNonce(), 19 | nativeVestingCode: nativeVestingArtifacts.code, 20 | vestingCode: vestingArtifacts.code, 21 | }, 22 | constructorParams: { 23 | indexCode: indexArtifacts.code, 24 | indexDeployValue: locklift.utils.toNano(0.1), 25 | indexDestroyValue: locklift.utils.toNano(0.1), 26 | }, 27 | value: locklift.utils.toNano(5), 28 | }, 29 | locklift.privateRPC.deployContract, 30 | ); 31 | 32 | console.log(`VestingFactory address: ${vestingFactory.address.toString()}`); 33 | } 34 | 35 | main() 36 | .then(() => process.exit(0)) 37 | .catch(e => { 38 | console.log(e); 39 | process.exit(1); 40 | }); 41 | -------------------------------------------------------------------------------- /script/2-indexing-example.ts: -------------------------------------------------------------------------------- 1 | import { Address } from "locklift"; 2 | 3 | export async function getUserIndexSaltedCodeHash( 4 | indexFactory: Address, 5 | indexCode: string, 6 | indexName: "recipient" | "creator", 7 | contractType: "Vesting" | "NativeVesting", 8 | user: Address, 9 | ): Promise { 10 | const saltValuePacked = await locklift.provider.packIntoCell({ 11 | abiVersion: "2.2", 12 | structure: [ 13 | { name: "user", type: "address" }, 14 | { name: "contractType", type: "string" }, 15 | ] as const, 16 | data: { 17 | user: user, 18 | contractType: contractType, 19 | }, 20 | }); 21 | const { hash: saltedCodeHash } = await locklift.provider.setCodeSalt({ 22 | code: indexCode, 23 | salt: { 24 | abiVersion: "2.2", 25 | structure: [ 26 | { name: "indexFactory", type: "address" }, 27 | { name: "saltKey", type: "string" }, 28 | { name: "saltValue", type: "cell" }, 29 | ] as const, 30 | data: { 31 | indexFactory: indexFactory, 32 | saltKey: indexName, 33 | saltValue: saltValuePacked.boc, 34 | }, 35 | }, 36 | }); 37 | 38 | return "0x" + saltedCodeHash; 39 | } 40 | 41 | export async function getTokenIndexSaltedCodeHash( 42 | indexFactory: Address, 43 | indexCode: string, 44 | token: Address, 45 | ): Promise { 46 | const saltValuePacked = await locklift.provider.packIntoCell({ 47 | abiVersion: "2.2", 48 | structure: [{ name: "token", type: "address" }] as const, 49 | data: { 50 | token: token, 51 | }, 52 | }); 53 | const { hash: saltedCodeHash } = await locklift.provider.setCodeSalt({ 54 | code: indexCode, 55 | salt: { 56 | abiVersion: "2.2", 57 | structure: [ 58 | { name: "indexFactory", type: "address" }, 59 | { name: "saltKey", type: "string" }, 60 | { name: "saltValue", type: "cell" }, 61 | ] as const, 62 | data: { 63 | indexFactory: indexFactory, 64 | saltKey: "token", 65 | saltValue: saltValuePacked.boc, 66 | }, 67 | }, 68 | }); 69 | 70 | return "0x" + saltedCodeHash; 71 | } 72 | 73 | async function getVestingDetails( 74 | index: Address, 75 | vestingType: "NativeVesting" | "Vesting", 76 | ) { 77 | // Create instance of the Index contract 78 | const indexContract = locklift.factory.getDeployedContract("Index", index); 79 | 80 | // Get native vesting contract address 81 | const { value0: indexedContract } = await indexContract.methods 82 | .getIndexedContract({ answerId: 0 }) 83 | .call(); 84 | 85 | const vesting = locklift.factory.getDeployedContract( 86 | vestingType, 87 | indexedContract, 88 | ); 89 | 90 | const vestingDetails = await vesting.methods.getDetails().call(); 91 | return { vesting: indexedContract, ...vestingDetails }; 92 | } 93 | 94 | 95 | async function main() { 96 | // Contracts addresses 97 | const vestingFactoryAddress = new Address( 98 | "0:add637c8bc32f0f5b9662288538a35b9d9fa25b3201c3b439264f6bd0b8b9a46", 99 | ); 100 | 101 | const creator = new Address( 102 | "0:5a533a7769a0bae38213eb986ac288b578dc902eabbea3df23110cdcde24a79a", 103 | ); 104 | 105 | const recipient = new Address( 106 | "0:bd4fd31869e0a89d1aa154622961841b4a96af46430fab2e27d5b766b5ead850", 107 | ); 108 | 109 | // you can get contract instance with everscale-inpage-provider.Contract 110 | const vestingFactory = locklift.factory.getDeployedContract( 111 | "VestingFactory", 112 | vestingFactoryAddress, 113 | ); 114 | 115 | // --------------------------------------------------------------------------- 116 | // Deploy NativeVesting contract with VestingFactory 117 | // --------------------------------------------------------------------------- 118 | // setup vesting params 119 | const start = Math.floor(locklift.testing.getCurrentTime() / 1000) + 15; 120 | const end = start + 2000; 121 | 122 | // create tx 123 | const tx = vestingFactory.methods 124 | .deployNativeVesting({ 125 | user: recipient, 126 | remainingGasTo: creator, // creator will receive remaining gas 127 | vesting_amount: locklift.utils.toNano(10), 128 | vesting_start: start, 129 | vesting_end: end, 130 | }) 131 | .send({ from: creator, amount: locklift.utils.toNano(3) }); 132 | 133 | // wait for tx finalization 134 | await locklift.transactions.waitFinalized(tx); 135 | console.log("tx:", (await tx).id.hash); 136 | // --------------------------------------------------------------------------- 137 | 138 | // receive index code with VestingFactory contract 139 | const { value0: indexCode } = await vestingFactory.methods 140 | .getIndexCode({ answerId: 0 }) 141 | .call(); 142 | 143 | // calculate codeHash for all indexes for given acc, accType and vesting contract Type 144 | const codeHash = await getUserIndexSaltedCodeHash( 145 | vestingFactoryAddress, 146 | indexCode, 147 | "recipient", 148 | "NativeVesting", 149 | recipient, 150 | ); 151 | console.log("codeHash", codeHash); 152 | 153 | // Filter all indexes contracts by given code hash 154 | const { accounts: indexes } = await locklift.provider.getAccountsByCodeHash({ 155 | codeHash, 156 | }); 157 | console.log(`find indexes: ${indexes.length}`); 158 | for (const index of indexes) { 159 | const vestingDetails = await getVestingDetails(index, "NativeVesting"); 160 | console.log(vestingDetails); 161 | } 162 | } 163 | 164 | main() 165 | .then(() => process.exit(0)) 166 | .catch(e => { 167 | console.log(e); 168 | process.exit(1); 169 | }); 170 | -------------------------------------------------------------------------------- /test/1-main.ts: -------------------------------------------------------------------------------- 1 | import { Contract, getRandomNonce, lockliftChai, toNano } from "locklift"; 2 | import { Account } from "locklift/everscale-client"; 3 | import { VestingAbi, VestingFactoryAbi } from "../build/factorySource"; 4 | import { 5 | bn, 6 | deployUser, 7 | setupTokenRoot, 8 | tryIncreaseTime, 9 | } from "./utils/common"; 10 | import { Token } from "./utils/wrappers/token"; 11 | import { TokenWallet } from "./utils/wrappers/token_wallet"; 12 | 13 | import chai, { expect } from "chai"; 14 | 15 | const logger = require("mocha-logger"); 16 | chai.use(lockliftChai); 17 | 18 | describe("Test linear vesting contract", async function () { 19 | this.timeout(100000000); 20 | 21 | let factory: Contract; 22 | let user: Account; 23 | let userTokenWallet: TokenWallet; 24 | let admin: Account; 25 | let adminTokenWallet: TokenWallet; 26 | let token: Token; 27 | let vesting_amount = 1_000_000_000; 28 | let vesting: Contract; 29 | let vestingTokenWallet: TokenWallet; 30 | let admin_initial_bal = 1_000_000_000_000; 31 | let period: number; 32 | let start: number; 33 | let end: number; 34 | let user_bal_cumulative = bn(0); 35 | let factoryDeployNonce = getRandomNonce(); 36 | 37 | describe("Setup basic contracts", async function () { 38 | it("Deploy users", async function () { 39 | user = await deployUser(); 40 | admin = await deployUser(); 41 | }); 42 | it("Deploy factory", async function () { 43 | admin = await deployUser(10); 44 | const signer = await locklift.keystore.getSigner("0"); 45 | 46 | const Vesting = locklift.factory.getContractArtifacts("Vesting"); 47 | const Index = locklift.factory.getContractArtifacts("Index"); 48 | const NativeVesting = 49 | locklift.factory.getContractArtifacts("NativeVesting"); 50 | 51 | const { contract: _contract } = await locklift.tracing.trace( 52 | locklift.factory.deployContract({ 53 | contract: "VestingFactory", 54 | constructorParams: { 55 | indexCode: Index.code, 56 | indexDeployValue: toNano(0.1), 57 | indexDestroyValue: toNano(0.1), 58 | }, 59 | initParams: { 60 | nativeVestingCode: NativeVesting.code, 61 | vestingCode: Vesting.code, 62 | deploy_nonce: factoryDeployNonce, 63 | }, 64 | value: toNano(5), 65 | publicKey: signer?.publicKey as string, 66 | }), 67 | ); 68 | factory = _contract; 69 | 70 | logger.log(`Factory address: ${factory.address}`); 71 | }); 72 | 73 | it("Deploy token", async function () { 74 | token = await setupTokenRoot("Wrapped Venom", "WVENOM", user); 75 | await token.mint(admin_initial_bal, admin); 76 | adminTokenWallet = await token.wallet(admin); 77 | userTokenWallet = await token.wallet(user); 78 | }); 79 | }); 80 | 81 | describe("Test vesting", async function () { 82 | it("Deploy vesting with past start date", async function () { 83 | start = Math.floor(locklift.testing.getCurrentTime() / 1000) - 1000; 84 | end = start + 2000; 85 | 86 | locklift.tracing.setAllowedCodes({ compute: [1002] }); 87 | const { traceTree } = await locklift.tracing.trace( 88 | factory.methods 89 | .deployVesting({ 90 | user: user.address, 91 | remainingGasTo: user.address, 92 | token: token.address, 93 | vesting_amount: vesting_amount, 94 | vesting_start: start, 95 | vesting_end: end, 96 | }) 97 | .send({ from: user.address, amount: toNano(3) }), 98 | ); 99 | locklift.tracing.removeAllowedCodes({ compute: [1002] }); 100 | 101 | expect(traceTree).to.error(1002); 102 | }); 103 | it("Deploy vesting with end date earlier than start", async function () { 104 | start = Math.floor(locklift.testing.getCurrentTime() / 1000) + 20; 105 | end = start - 10; 106 | 107 | locklift.tracing.setAllowedCodes({ compute: [1002] }); 108 | const { traceTree } = await locklift.tracing.trace( 109 | factory.methods 110 | .deployVesting({ 111 | user: user.address, 112 | remainingGasTo: user.address, 113 | token: token.address, 114 | vesting_amount: vesting_amount, 115 | vesting_start: start, 116 | vesting_end: end, 117 | }) 118 | .send({ from: user.address, amount: toNano(3) }), 119 | ); 120 | locklift.tracing.removeAllowedCodes({ compute: [1002] }); 121 | 122 | expect(traceTree).to.error(1002); 123 | }); 124 | it("Deploy vesting with insufficient value", async function () { 125 | start = Math.floor(locklift.testing.getCurrentTime() / 1000) + 15; 126 | end = start + 20; 127 | period = end - start; 128 | 129 | locklift.tracing.setAllowedCodes({ compute: [1003] }); 130 | const { traceTree } = await locklift.tracing.trace( 131 | factory.methods 132 | .deployVesting({ 133 | user: user.address, 134 | remainingGasTo: user.address, 135 | token: token.address, 136 | vesting_amount: vesting_amount, 137 | vesting_start: start, 138 | vesting_end: end, 139 | }) 140 | .send({ from: user.address, amount: toNano(1) }), 141 | ); 142 | locklift.tracing.removeAllowedCodes({ compute: [1003] }); 143 | expect(traceTree).to.error(1003); 144 | }); 145 | 146 | it("Deploy vesting", async function () { 147 | start = Math.floor(locklift.testing.getCurrentTime() / 1000) + 15; 148 | end = start + 20; 149 | period = end - start; 150 | 151 | await locklift.tracing.trace( 152 | factory.methods 153 | .deployVesting({ 154 | user: user.address, 155 | remainingGasTo: user.address, 156 | token: token.address, 157 | vesting_amount: vesting_amount, 158 | vesting_start: start, 159 | vesting_end: end, 160 | }) 161 | .send({ from: user.address, amount: toNano(3) }), 162 | ); 163 | 164 | // @ts-ignore 165 | const event = ( 166 | await factory.getPastEvents({ 167 | filter: event => event.event === "NewVesting", 168 | }) 169 | ).events.shift() as any; 170 | expect(event.data.user.toString()).to.be.eq(user.address.toString()); 171 | 172 | vesting = await locklift.factory.getDeployedContract( 173 | "Vesting", 174 | event.data.vesting, 175 | ); 176 | vestingTokenWallet = await token.wallet({ 177 | address: vesting.address, 178 | } as Account); 179 | logger.log(`Vesting address - ${vesting.address}`); 180 | }); 181 | 182 | it("Deploy vesting", async function () { 183 | start = Math.floor(locklift.testing.getCurrentTime() / 1000) + 15; 184 | end = start + 20; 185 | period = end - start; 186 | 187 | await locklift.tracing.trace( 188 | factory.methods 189 | .deployVesting({ 190 | user: user.address, 191 | remainingGasTo: user.address, 192 | token: token.address, 193 | vesting_amount: vesting_amount, 194 | vesting_start: start, 195 | vesting_end: end, 196 | }) 197 | .send({ from: user.address, amount: toNano(3) }), 198 | ); 199 | 200 | // @ts-ignore 201 | const event = ( 202 | await factory.getPastEvents({ 203 | filter: event => event.event === "NewVesting", 204 | }) 205 | ).events.shift() as any; 206 | expect(event.data.user.toString()).to.be.eq(user.address.toString()); 207 | 208 | vesting = await locklift.factory.getDeployedContract( 209 | "Vesting", 210 | event.data.vesting, 211 | ); 212 | vestingTokenWallet = await token.wallet({ 213 | address: vesting.address, 214 | } as Account); 215 | logger.log(`Vesting address - ${vesting.address}`); 216 | }); 217 | 218 | it("Send bad token amount to vesting", async function () { 219 | const bad_amount = 123; 220 | const { traceTree } = await locklift.tracing.trace( 221 | adminTokenWallet.transfer(bad_amount, vesting.address, "", toNano(1)), 222 | ); 223 | // await traceTree?.beautyPrint(); 224 | expect(traceTree).to.emit("BadDeposit").withNamedArgs({ 225 | sender: admin.address, 226 | amount: bad_amount.toFixed(), 227 | }); 228 | 229 | // check funds not sent 230 | const admin_bal = await adminTokenWallet.balance(); 231 | expect(admin_bal.toString()).to.be.eq( 232 | admin_initial_bal.toString(), 233 | "Bad tokens lost", 234 | ); 235 | }); 236 | 237 | it("Send correct token amount", async function () { 238 | const { traceTree } = await locklift.tracing.trace( 239 | adminTokenWallet.transfer( 240 | vesting_amount, 241 | vesting.address, 242 | "", 243 | toNano(1), 244 | ), 245 | ); 246 | expect(traceTree).to.emit("Deposit").withNamedArgs({ 247 | sender: admin.address, 248 | amount: vesting_amount.toFixed(), 249 | }); 250 | const details = await vesting.methods.getDetails({}).call(); 251 | expect(details._filled).to.be.eq(true, "Not filled"); 252 | expect(details._tokenBalance.toString()).to.be.eq( 253 | vesting_amount.toString(), 254 | "Bad token balance", 255 | ); 256 | }); 257 | 258 | it("Send redundant tokens", async function () { 259 | const admin_bal_before = await adminTokenWallet.balance(); 260 | 261 | const { traceTree } = await locklift.tracing.trace( 262 | adminTokenWallet.transfer( 263 | vesting_amount, 264 | vesting.address, 265 | "", 266 | toNano(1), 267 | ), 268 | ); 269 | expect(traceTree).to.emit("BadDeposit").withNamedArgs({ 270 | sender: admin.address, 271 | amount: vesting_amount.toFixed(), 272 | }); 273 | // check funds not sent 274 | const admin_bal = await adminTokenWallet.balance(); 275 | expect(admin_bal.toString()).to.be.eq( 276 | admin_bal_before.toString(), 277 | "Bad tokens lost", 278 | ); 279 | }); 280 | 281 | it("User claims before vesting starts", async function () { 282 | locklift.tracing.setAllowedCodes({ compute: [1004] }); 283 | const { traceTree } = await locklift.tracing.trace( 284 | vesting.methods 285 | .claim({}) 286 | .send({ from: user.address, amount: toNano(2) }), 287 | ); 288 | locklift.tracing.removeAllowedCodes({ compute: [1004] }); 289 | expect(traceTree).to.error(1004); 290 | }); 291 | 292 | it("User claims", async function () { 293 | await tryIncreaseTime(20); 294 | 295 | const { traceTree } = await locklift.tracing.trace( 296 | vesting.methods 297 | .claim({}) 298 | .send({ from: user.address, amount: toNano(2) }), 299 | ); 300 | 301 | const details = await vesting.methods.getDetails({}).call(); 302 | const claim_time = Number(details._lastClaimTime); 303 | const vesting_start = Number(details._vestingStart); 304 | const passed = claim_time - vesting_start; 305 | 306 | const amount = Math.floor((vesting_amount * passed) / period); 307 | logger.log( 308 | `Time passed - ${passed} (${((passed / period) * 100).toPrecision( 309 | 2, 310 | )}%), tokens should be paid - ${amount}`, 311 | ); 312 | 313 | const vesting_bal = await vestingTokenWallet.balance(); 314 | expect(traceTree).to.emit("Claim").withNamedArgs({ 315 | amount: amount.toFixed(), 316 | remaining_amount: vesting_bal.toString(), 317 | }); 318 | logger.log(`Remaining balance - ${vesting_start.toString()}`); 319 | 320 | const user_bal = await userTokenWallet.balance(); 321 | expect(user_bal.toString()).to.be.eq(amount.toFixed()); 322 | user_bal_cumulative = bn(user_bal.toString()); 323 | }); 324 | 325 | it("User claims again", async function () { 326 | const prev_details = await vesting.methods.getDetails().call(); 327 | const prev_claim_time = Number(prev_details._lastClaimTime); 328 | const vesting_balance = Number(prev_details._tokenBalance); 329 | 330 | await tryIncreaseTime(5); 331 | 332 | const { traceTree } = await locklift.tracing.trace( 333 | vesting.methods 334 | .claim({}) 335 | .send({ from: user.address, amount: toNano(2) }), 336 | ); 337 | 338 | const details = await vesting.methods.getDetails().call(); 339 | const claim_time = Number(details._lastClaimTime); 340 | const period = end - prev_claim_time; 341 | const passed = claim_time - prev_claim_time; 342 | 343 | const amount = Math.floor((vesting_balance * passed) / period); 344 | logger.log( 345 | `Time passed - ${passed} (${((passed / period) * 100).toPrecision( 346 | 2, 347 | )}%), tokens should be paid - ${amount}`, 348 | ); 349 | 350 | const vesting_bal = await vestingTokenWallet.balance(); 351 | expect(traceTree).to.emit("Claim").withNamedArgs({ 352 | amount: amount.toFixed(), 353 | remaining_amount: vesting_bal.toString(), 354 | }); 355 | 356 | const user_bal = await userTokenWallet.balance(); 357 | user_bal_cumulative = user_bal_cumulative.plus(bn(amount.toFixed())); 358 | expect(user_bal.toString()).to.be.eq( 359 | user_bal_cumulative.toString(), 360 | "User not paid", 361 | ); 362 | }); 363 | 364 | it("User claims after vesting ends", async function () { 365 | await tryIncreaseTime(15); 366 | 367 | const prev_details = await vesting.methods.getDetails().call(); 368 | const prev_claim_time = Number(prev_details._lastClaimTime); 369 | const vesting_balance = Number(prev_details._tokenBalance); 370 | 371 | const { traceTree } = await locklift.tracing.trace( 372 | vesting.methods 373 | .claim({}) 374 | .send({ from: user.address, amount: toNano(2) }), 375 | ); 376 | 377 | const details = await vesting.methods.getDetails().call(); 378 | const claim_time = Number(details._lastClaimTime); 379 | const period = end - prev_claim_time; 380 | const passed = claim_time - prev_claim_time; 381 | 382 | const amount = vesting_balance; 383 | logger.log( 384 | `Time passed - ${passed} (${((passed / period) * 100).toPrecision( 385 | 2, 386 | )}%), tokens should be paid - ${amount}`, 387 | ); 388 | 389 | const vesting_bal = await vestingTokenWallet.balance(); 390 | expect(traceTree).to.emit("Claim").withNamedArgs({ 391 | amount: amount.toFixed(), 392 | remaining_amount: vesting_bal.toString(), 393 | }); 394 | 395 | const user_bal = await userTokenWallet.balance(); 396 | user_bal_cumulative = user_bal_cumulative.plus(bn(amount.toFixed())); 397 | expect(user_bal.toString()).to.be.eq( 398 | user_bal_cumulative.toString(), 399 | "User not paid", 400 | ); 401 | 402 | expect(traceTree).to.emit("Vested"); 403 | 404 | expect(details._vested).to.be.eq(true, "Not vested"); 405 | expect(details._tokenBalance.toString()).to.be.eq("0", "Bad balance"); 406 | }); 407 | }); 408 | }); 409 | -------------------------------------------------------------------------------- /test/2-native-main.ts: -------------------------------------------------------------------------------- 1 | import { Contract, getRandomNonce, lockliftChai, toNano } from "locklift"; 2 | import { Account } from "locklift/everscale-client"; 3 | import { NativeVestingAbi, VestingFactoryAbi } from "../build/factorySource"; 4 | import { bn, deployUser, tryIncreaseTime } from "./utils/common"; 5 | 6 | import chai, { expect } from "chai"; 7 | 8 | const logger = require("mocha-logger"); 9 | chai.use(lockliftChai); 10 | 11 | describe("Test native linear vesting contract", async function () { 12 | this.timeout(100000000); 13 | 14 | let factory: Contract; 15 | let user: Account; 16 | let admin: Account; 17 | let vesting_amount = toNano(10); 18 | let vesting: Contract; 19 | let period: number; 20 | let start: number; 21 | let end: number; 22 | let user_bal_cumulative = bn(0); 23 | let factoryDeployNonce = getRandomNonce(); 24 | 25 | describe("Setup basic contracts", async function () { 26 | it("Deploy users", async function () { 27 | user = await deployUser(); 28 | admin = await deployUser(); 29 | }); 30 | 31 | it("Deploy factory", async function () { 32 | const signer = await locklift.keystore.getSigner("0"); 33 | 34 | const Vesting = locklift.factory.getContractArtifacts("Vesting"); 35 | const Index = locklift.factory.getContractArtifacts("Index"); 36 | const NativeVesting = 37 | locklift.factory.getContractArtifacts("NativeVesting"); 38 | 39 | const { contract: _contract } = await locklift.tracing.trace( 40 | locklift.factory.deployContract({ 41 | contract: "VestingFactory", 42 | constructorParams: { 43 | indexCode: Index.code, 44 | indexDeployValue: toNano(0.1), 45 | indexDestroyValue: toNano(0.1), 46 | }, 47 | initParams: { 48 | nativeVestingCode: NativeVesting.code, 49 | vestingCode: Vesting.code, 50 | deploy_nonce: factoryDeployNonce, 51 | }, 52 | value: toNano(5), 53 | publicKey: signer?.publicKey as string, 54 | }), 55 | ); 56 | factory = _contract; 57 | 58 | logger.log(`Factory address: ${factory.address}`); 59 | }); 60 | }); 61 | 62 | describe("Test native vesting", async function () { 63 | it("Deploy vesting with past start date", async function () { 64 | start = Math.floor(locklift.testing.getCurrentTime() / 1000) - 1000; 65 | end = start + 2000; 66 | 67 | locklift.tracing.setAllowedCodes({ compute: [1002] }); 68 | const { traceTree } = await locklift.tracing.trace( 69 | factory.methods 70 | .deployNativeVesting({ 71 | user: user.address, 72 | remainingGasTo: user.address, 73 | vesting_amount: vesting_amount, 74 | vesting_start: start, 75 | vesting_end: end, 76 | }) 77 | .send({ from: user.address, amount: toNano(3) }), 78 | ); 79 | locklift.tracing.removeAllowedCodes({ compute: [1002] }); 80 | 81 | expect(traceTree).to.error(1002); 82 | }); 83 | it("Deploy vesting with end date earlier than start", async function () { 84 | start = Math.floor(locklift.testing.getCurrentTime() / 1000) + 20; 85 | end = start - 10; 86 | 87 | locklift.tracing.setAllowedCodes({ compute: [1002] }); 88 | const { traceTree } = await locklift.tracing.trace( 89 | factory.methods 90 | .deployNativeVesting({ 91 | user: user.address, 92 | remainingGasTo: user.address, 93 | vesting_amount: vesting_amount, 94 | vesting_start: start, 95 | vesting_end: end, 96 | }) 97 | .send({ from: user.address, amount: toNano(3) }), 98 | ); 99 | locklift.tracing.removeAllowedCodes({ compute: [1002] }); 100 | 101 | expect(traceTree).to.error(1002); 102 | }); 103 | 104 | it("Deploy vesting with insufficient value", async function () { 105 | start = Math.floor(locklift.testing.getCurrentTime() / 1000) + 15; 106 | end = start + 20; 107 | period = end - start; 108 | locklift.tracing.setAllowedCodes({ compute: [1003] }); 109 | 110 | const { traceTree } = await locklift.tracing.trace( 111 | factory.methods 112 | .deployNativeVesting({ 113 | user: user.address, 114 | remainingGasTo: user.address, 115 | vesting_amount: vesting_amount, 116 | vesting_start: start, 117 | vesting_end: end, 118 | }) 119 | .send({ from: user.address, amount: toNano(1) }), 120 | ); 121 | 122 | locklift.tracing.removeAllowedCodes({ compute: [1003] }); 123 | expect(traceTree).to.error(1003); 124 | }); 125 | 126 | it("Deploy vesting", async function () { 127 | start = Math.floor(locklift.testing.getCurrentTime() / 1000) + 15; 128 | end = start + 20; 129 | period = end - start; 130 | 131 | await locklift.tracing.trace( 132 | factory.methods 133 | .deployNativeVesting({ 134 | user: user.address, 135 | remainingGasTo: user.address, 136 | vesting_amount: vesting_amount, 137 | vesting_start: start, 138 | vesting_end: end, 139 | }) 140 | .send({ from: user.address, amount: toNano(3) }), 141 | ); 142 | 143 | // @ts-ignore 144 | const event = ( 145 | await factory.getPastEvents({ 146 | filter: event => event.event === "NewVesting", 147 | }) 148 | ).events.shift() as any; 149 | expect(event.data.user.toString()).to.be.eq(user.address.toString()); 150 | 151 | vesting = await locklift.factory.getDeployedContract( 152 | "NativeVesting", 153 | event.data.vesting, 154 | ); 155 | logger.log(`Vesting address - ${vesting.address}`); 156 | }); 157 | 158 | it("Send correct amount", async function () { 159 | const { traceTree } = await locklift.tracing.trace( 160 | vesting.methods.deposit({ send_gas_to: admin.address }).send({ 161 | from: admin.address, 162 | amount: bn(vesting_amount).plus(toNano(2)).toFixed(), 163 | }), 164 | ); 165 | expect(traceTree).to.emit("Deposit").withNamedArgs({ 166 | sender: admin.address, 167 | amount: vesting_amount, 168 | }); 169 | const details = await vesting.methods.getDetails({}).call(); 170 | expect(details._filled).to.be.eq(true, "Not filled"); 171 | expect(details._balance.toString()).to.be.eq( 172 | vesting_amount.toString(), 173 | "Bad token balance", 174 | ); 175 | }); 176 | 177 | it("User claims before vesting starts", async function () { 178 | locklift.tracing.setAllowedCodes({ compute: [1004] }); 179 | const { traceTree } = await locklift.tracing.trace( 180 | vesting.methods 181 | .claim({}) 182 | .send({ from: user.address, amount: toNano(2) }), 183 | ); 184 | locklift.tracing.removeAllowedCodes({ compute: [1004] }); 185 | expect(traceTree).to.error(1004); 186 | }); 187 | 188 | it("User claims", async function () { 189 | await tryIncreaseTime(20); 190 | 191 | const { traceTree } = await locklift.tracing.trace( 192 | vesting.methods 193 | .claim({}) 194 | .send({ from: user.address, amount: toNano(2) }), 195 | ); 196 | 197 | const details = await vesting.methods.getDetails({}).call(); 198 | const claim_time = Number(details._lastClaimTime); 199 | const vesting_start = Number(details._vestingStart); 200 | const passed = claim_time - vesting_start; 201 | 202 | const amount = bn(vesting_amount).times(passed).idiv(period); 203 | logger.log( 204 | `Time passed - ${passed} (${((passed / period) * 100).toPrecision( 205 | 2, 206 | )}%), tokens should be paid - ${amount}`, 207 | ); 208 | 209 | expect(traceTree).to.emit("Claim").withNamedArgs({ 210 | amount: amount.toFixed(), 211 | }); 212 | 213 | user_bal_cumulative = bn(amount.toFixed()); 214 | }); 215 | 216 | it("User claims again", async function () { 217 | const prev_details = await vesting.methods.getDetails().call(); 218 | const prev_claim_time = Number(prev_details._lastClaimTime); 219 | const vesting_balance = Number(prev_details._balance); 220 | 221 | await tryIncreaseTime(5); 222 | 223 | const { traceTree } = await locklift.tracing.trace( 224 | vesting.methods 225 | .claim({}) 226 | .send({ from: user.address, amount: toNano(2) }), 227 | ); 228 | 229 | const details = await vesting.methods.getDetails().call(); 230 | const claim_time = Number(details._lastClaimTime); 231 | const period = end - prev_claim_time; 232 | const passed = claim_time - prev_claim_time; 233 | 234 | const amount = bn(vesting_balance).times(passed).idiv(period); 235 | logger.log( 236 | `Time passed - ${passed} (${((passed / period) * 100).toPrecision( 237 | 2, 238 | )}%), tokens should be paid - ${amount}`, 239 | ); 240 | 241 | expect(traceTree).to.emit("Claim").withNamedArgs({ 242 | amount: amount.toFixed(), 243 | }); 244 | user_bal_cumulative = user_bal_cumulative.plus(amount.toFixed()); 245 | }); 246 | 247 | it("User claims after vesting ends", async function () { 248 | await tryIncreaseTime(15); 249 | 250 | const prev_details = await vesting.methods.getDetails().call(); 251 | const prev_claim_time = Number(prev_details._lastClaimTime); 252 | const vesting_balance = Number(prev_details._balance); 253 | 254 | const { traceTree } = await locklift.tracing.trace( 255 | vesting.methods 256 | .claim({}) 257 | .send({ from: user.address, amount: toNano(2) }), 258 | ); 259 | 260 | const details = await vesting.methods.getDetails().call(); 261 | const claim_time = Number(details._lastClaimTime); 262 | const period = end - prev_claim_time; 263 | const passed = claim_time - prev_claim_time; 264 | 265 | const amount = vesting_balance; 266 | logger.log( 267 | `Time passed - ${passed} (${((passed / period) * 100).toPrecision( 268 | 2, 269 | )}%), tokens should be paid - ${amount}`, 270 | ); 271 | 272 | expect(traceTree).to.emit("Claim").withNamedArgs({ 273 | amount: amount.toFixed(), 274 | }); 275 | 276 | user_bal_cumulative = user_bal_cumulative.plus(bn(amount.toFixed())); 277 | expect(user_bal_cumulative.toFixed()).to.be.eq(vesting_amount); 278 | 279 | expect(traceTree).to.emit("Vested"); 280 | 281 | expect(details._vested).to.be.eq(true, "Not vested"); 282 | expect(details._balance.toString()).to.be.eq("0", "Bad balance"); 283 | }); 284 | }); 285 | }); 286 | -------------------------------------------------------------------------------- /test/3-indexer.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | import { Address, Contract } from "locklift"; 3 | import { Account } from "locklift/everscale-client"; 4 | import { FactorySource } from "../build/factorySource"; 5 | import { bn, deployUser, setupTokenRoot } from "./utils/common"; 6 | import { Token } from "./utils/wrappers/token"; 7 | import { TokenWallet } from "./utils/wrappers/token_wallet"; 8 | 9 | const logger = require("mocha-logger"); 10 | 11 | describe("Test index creation for vesting contracts", async function () { 12 | let admin: Account; 13 | let adminTokenWallet: TokenWallet; 14 | let user0: Account; 15 | let user0TokenWallet: TokenWallet; 16 | let user1: Account; 17 | let user1TokenWallet: TokenWallet; 18 | let user2: Account; 19 | let user2TokenWallet: TokenWallet; 20 | 21 | let token: Token; 22 | 23 | let factory: Contract; 24 | 25 | const vestingArtifacts = locklift.factory.getContractArtifacts("Vesting"); 26 | const nativeVestingArtifacts = 27 | locklift.factory.getContractArtifacts("NativeVesting"); 28 | const indexArtifacts = locklift.factory.getContractArtifacts("Index"); 29 | 30 | before("Setup contracts", async function () { 31 | admin = await deployUser(20, "admin"); 32 | user0 = await deployUser(20, "user0"); 33 | user1 = await deployUser(20, "user1"); 34 | user2 = await deployUser(20, "user2"); 35 | 36 | const signer = await locklift.keystore.getSigner("0"); 37 | const deployNonce = locklift.utils.getRandomNonce(); 38 | 39 | const { contract: _factory } = await locklift.factory.deployContract({ 40 | contract: "VestingFactory", 41 | publicKey: signer?.publicKey as string, 42 | initParams: { 43 | nativeVestingCode: nativeVestingArtifacts.code, 44 | vestingCode: vestingArtifacts.code, 45 | deploy_nonce: deployNonce, 46 | }, 47 | constructorParams: { 48 | indexCode: indexArtifacts.code, 49 | indexDeployValue: locklift.utils.toNano(0.1), 50 | indexDestroyValue: locklift.utils.toNano(0.1), 51 | }, 52 | value: locklift.utils.toNano(5), 53 | }); 54 | factory = _factory; 55 | logger.log(`Factory address: ${factory.address}`); 56 | 57 | token = await setupTokenRoot("Example Token", "EXMPL", admin); 58 | adminTokenWallet = await token.wallet(admin); 59 | user0TokenWallet = await token.wallet(user0); 60 | user1TokenWallet = await token.wallet(user1); 61 | user2TokenWallet = await token.wallet(user2); 62 | }); 63 | it("should deploy 2 indexes for user0 as recipient and 3 indexes for user1 as creator", async function () { 64 | const start = Math.floor(locklift.testing.getCurrentTime() / 1000) + 15; 65 | const end = start + 20; 66 | 67 | await token.mint(bn(100).multipliedBy(1e18).toFixed(), user1); 68 | 69 | await locklift.tracing.trace( 70 | factory.methods 71 | .deployVesting({ 72 | user: user0.address, 73 | remainingGasTo: user1.address, 74 | token: token.address, 75 | vesting_amount: bn(100).multipliedBy(1e18).toFixed(), 76 | vesting_start: start, 77 | vesting_end: end, 78 | }) 79 | .send({ 80 | from: user1.address, 81 | amount: locklift.utils.toNano(3), 82 | }), 83 | ); 84 | 85 | await locklift.tracing.trace( 86 | factory.methods 87 | .deployVesting({ 88 | user: user0.address, 89 | remainingGasTo: user1.address, 90 | token: token.address, 91 | vesting_amount: bn(100).multipliedBy(1e18).toFixed(), 92 | vesting_start: start, 93 | vesting_end: end, 94 | }) 95 | .send({ 96 | from: user1.address, 97 | amount: locklift.utils.toNano(3), 98 | }), 99 | ); 100 | 101 | await locklift.tracing.trace( 102 | factory.methods 103 | .deployVesting({ 104 | user: user2.address, 105 | remainingGasTo: user1.address, 106 | token: token.address, 107 | vesting_amount: bn(100).multipliedBy(1e18).toFixed(), 108 | vesting_start: start, 109 | vesting_end: end, 110 | }) 111 | .send({ 112 | from: user1.address, 113 | amount: locklift.utils.toNano(3), 114 | }), 115 | ); 116 | const userIndexCodeHash = await getUserIndexSaltedCodeHash( 117 | factory.address, 118 | indexArtifacts.code, 119 | "recipient", 120 | "Vesting", 121 | user0.address, 122 | ); 123 | const creatorIndexCodeHash = await getUserIndexSaltedCodeHash( 124 | factory.address, 125 | indexArtifacts.code, 126 | "creator", 127 | "Vesting", 128 | user1.address, 129 | ); 130 | const tokenIndexCodeHash = await getTokenIndexSaltedCodeHash( 131 | factory.address, 132 | indexArtifacts.code, 133 | token.address, 134 | ); 135 | 136 | const { accounts: userAccs } = 137 | await locklift.provider.getAccountsByCodeHash({ 138 | codeHash: userIndexCodeHash, 139 | }); 140 | const { accounts: creatorAccs } = 141 | await locklift.provider.getAccountsByCodeHash({ 142 | codeHash: creatorIndexCodeHash, 143 | }); 144 | const { accounts: tokenAccs } = 145 | await locklift.provider.getAccountsByCodeHash({ 146 | codeHash: tokenIndexCodeHash, 147 | }); 148 | 149 | expect(userAccs.length).to.be.equal(2); 150 | expect(creatorAccs.length).to.be.equal(3); 151 | expect(tokenAccs.length).to.be.equal(3); 152 | }), 153 | it("should deploy 2 native vesting contract with indexes", async function () { 154 | const start = Math.floor(locklift.testing.getCurrentTime() / 1000) + 15; 155 | const end = start + 20; 156 | 157 | await token.mint(bn(100).multipliedBy(1e18).toFixed(), user1); 158 | 159 | await locklift.tracing.trace( 160 | factory.methods 161 | .deployNativeVesting({ 162 | user: user0.address, 163 | remainingGasTo: user1.address, 164 | vesting_amount: bn(1).multipliedBy(1e9).toFixed(), 165 | vesting_start: start, 166 | vesting_end: end, 167 | }) 168 | .send({ 169 | from: user1.address, 170 | amount: locklift.utils.toNano(3), 171 | }), 172 | ); 173 | 174 | await locklift.tracing.trace( 175 | factory.methods 176 | .deployNativeVesting({ 177 | user: user0.address, 178 | remainingGasTo: user1.address, 179 | vesting_amount: bn(1).multipliedBy(1e9).toFixed(), 180 | vesting_start: start, 181 | vesting_end: end, 182 | }) 183 | .send({ 184 | from: user1.address, 185 | amount: locklift.utils.toNano(3), 186 | }), 187 | ); 188 | 189 | const userIndexCodeHash = await getUserIndexSaltedCodeHash( 190 | factory.address, 191 | indexArtifacts.code, 192 | "recipient", 193 | "NativeVesting", 194 | user0.address, 195 | ); 196 | 197 | const creatorIndexCodeHash = await getUserIndexSaltedCodeHash( 198 | factory.address, 199 | indexArtifacts.code, 200 | "creator", 201 | "NativeVesting", 202 | user1.address, 203 | ); 204 | 205 | const { accounts: userAccs } = 206 | await locklift.provider.getAccountsByCodeHash({ 207 | codeHash: userIndexCodeHash, 208 | }); 209 | const { accounts: creatorAccs } = 210 | await locklift.provider.getAccountsByCodeHash({ 211 | codeHash: creatorIndexCodeHash, 212 | }); 213 | 214 | expect(userAccs.length).to.be.equal(2); 215 | expect(creatorAccs.length).to.be.equal(2); 216 | }); 217 | }); 218 | 219 | export async function getUserIndexSaltedCodeHash( 220 | indexFactory: Address, 221 | indexCode: string, 222 | indexName: "recipient" | "creator", 223 | contractType: "Vesting" | "NativeVesting", 224 | user: Address, 225 | ): Promise { 226 | const saltValuePacked = await locklift.provider.packIntoCell({ 227 | abiVersion: "2.2", 228 | structure: [ 229 | { name: "user", type: "address" }, 230 | { name: "contractType", type: "string" }, 231 | ] as const, 232 | data: { 233 | user: user, 234 | contractType: contractType, 235 | }, 236 | }); 237 | const { hash: saltedCodeHash } = await locklift.provider.setCodeSalt({ 238 | code: indexCode, 239 | salt: { 240 | abiVersion: "2.2", 241 | structure: [ 242 | { name: "indexFactory", type: "address" }, 243 | { name: "saltKey", type: "string" }, 244 | { name: "saltValue", type: "cell" }, 245 | ] as const, 246 | data: { 247 | indexFactory: indexFactory, 248 | saltKey: indexName, 249 | saltValue: saltValuePacked.boc, 250 | }, 251 | }, 252 | }); 253 | 254 | return "0x" + saltedCodeHash; 255 | } 256 | 257 | export async function getTokenIndexSaltedCodeHash( 258 | indexFactory: Address, 259 | indexCode: string, 260 | token: Address, 261 | ): Promise { 262 | const saltValuePacked = await locklift.provider.packIntoCell({ 263 | abiVersion: "2.2", 264 | structure: [{ name: "token", type: "address" }] as const, 265 | data: { 266 | token: token, 267 | }, 268 | }); 269 | const { hash: saltedCodeHash } = await locklift.provider.setCodeSalt({ 270 | code: indexCode, 271 | salt: { 272 | abiVersion: "2.2", 273 | structure: [ 274 | { name: "indexFactory", type: "address" }, 275 | { name: "saltKey", type: "string" }, 276 | { name: "saltValue", type: "cell" }, 277 | ] as const, 278 | data: { 279 | indexFactory: indexFactory, 280 | saltKey: "token", 281 | saltValue: saltValuePacked.boc, 282 | }, 283 | }, 284 | }); 285 | 286 | return "0x" + saltedCodeHash; 287 | } 288 | -------------------------------------------------------------------------------- /test/contracts/Wallet.sol: -------------------------------------------------------------------------------- 1 | pragma ever-solidity ^0.62.0; 2 | pragma AbiHeader expire; 3 | pragma AbiHeader pubkey; 4 | 5 | import '@broxus/contracts/contracts/wallets/Account.tsol'; 6 | 7 | 8 | contract Wallet is Account {} 9 | -------------------------------------------------------------------------------- /test/contracts/build/Wallet.abi.json: -------------------------------------------------------------------------------- 1 | { 2 | "ABI version": 2, 3 | "version": "2.2", 4 | "header": ["pubkey", "time", "expire"], 5 | "functions": [ 6 | { 7 | "name": "sendTransaction", 8 | "inputs": [ 9 | {"name":"dest","type":"address"}, 10 | {"name":"value","type":"uint128"}, 11 | {"name":"bounce","type":"bool"}, 12 | {"name":"flags","type":"uint8"}, 13 | {"name":"payload","type":"cell"} 14 | ], 15 | "outputs": [ 16 | ] 17 | }, 18 | { 19 | "name": "transferOwnership", 20 | "inputs": [ 21 | {"name":"newOwner","type":"uint256"} 22 | ], 23 | "outputs": [ 24 | ] 25 | }, 26 | { 27 | "name": "constructor", 28 | "inputs": [ 29 | ], 30 | "outputs": [ 31 | ] 32 | }, 33 | { 34 | "name": "owner", 35 | "inputs": [ 36 | ], 37 | "outputs": [ 38 | {"name":"owner","type":"uint256"} 39 | ] 40 | }, 41 | { 42 | "name": "_randomNonce", 43 | "inputs": [ 44 | ], 45 | "outputs": [ 46 | {"name":"_randomNonce","type":"uint256"} 47 | ] 48 | } 49 | ], 50 | "data": [ 51 | {"key":1,"name":"_randomNonce","type":"uint256"} 52 | ], 53 | "events": [ 54 | { 55 | "name": "OwnershipTransferred", 56 | "inputs": [ 57 | {"name":"previousOwner","type":"uint256"}, 58 | {"name":"newOwner","type":"uint256"} 59 | ], 60 | "outputs": [ 61 | ] 62 | } 63 | ], 64 | "fields": [ 65 | {"name":"_pubkey","type":"uint256"}, 66 | {"name":"_timestamp","type":"uint64"}, 67 | {"name":"_constructorFlag","type":"bool"}, 68 | {"name":"owner","type":"uint256"}, 69 | {"name":"_randomNonce","type":"uint256"} 70 | ] 71 | } 72 | -------------------------------------------------------------------------------- /test/contracts/build/Wallet.base64: -------------------------------------------------------------------------------- 1 | te6ccgECGAEAAuQAAgE0AwEBAcACAEPQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgBCSK7VMg4wMgwP/jAiDA/uMC8gsVBQQXArztRNDXScMB+GYh2zzTAAGOHIMI1xgg+QEB0wABlNP/AwGTAvhC4iD4ZfkQ8qiV0wAB8nri0z8B+EMhufK0IPgjgQPoqIIIG3dAoLnytPhj0x8B+CO88rnTHwHbPPI8CAYDSu1E0NdJwwH4ZiLQ1wsDqTgA3CHHAOMCIdcNH/K8IeMDAds88jwUFAYCKCCCEFhakGS74wIgghBotV8/uuMCCQcDUjD4Qm7jAPhG8nPR+EUgbpIwcN74Qrry5E/4APhFIG6SMHDe2zzbPPIACA0LAWLtRNDXScIBjiZw7UTQ9AVwcSKAQPQOb5GT1wv/3vhr+GqAQPQO8r3XC//4YnD4Y+MNEwRQIIIQEXjpvbrjAiCCEDtTMx+64wIgghBM7mRsuuMCIIIQWFqQZLrjAhIRDgoDNjD4RvLgTPhCbuMAIZPU0dDe0//R2zww2zzyABMMCwAs+Ev4SvhD+ELIy//LP8+Dy//L/8ntVAEs+EUgbpIwcN74Srry5E0g8uRO+ADbPA0ARvhKIfhqjQRwAAAAAAAAAAAAAAAAFNs0/KDIzsv/y//JcPsAA0Iw+Eby4Ez4Qm7jACGT1NHQ3vpA03/SANMH1NHbPOMA8gATEA8AKO1E0NP/0z8x+ENYyMv/yz/Oye1UAFT4RSBukjBw3vhKuvLkTfgAVQJVEsjPhYDKAM+EQM4B+gJxzwtqzMkB+wABUDDR2zz4SyGOHI0EcAAAAAAAAAAAAAAAAC7UzMfgyM7L/8lw+wDe8gATAVAw0ds8+EohjhyNBHAAAAAAAAAAAAAAAAAkXjpvYMjOy//JcPsA3vIAEwAu7UTQ0//TP9MAMdP/0//R+Gv4avhj+GIACvhG8uBMAgr0pCD0oRcWABRzb2wgMC42Mi4wAAA= -------------------------------------------------------------------------------- /test/contracts/build/Wallet.code: -------------------------------------------------------------------------------- 1 | .version sol 0.62.0 2 | 3 | .macro constructor 4 | DROP 5 | GETGLOB 2 6 | ISNULL 7 | IFREF { 8 | CALL $c4_to_c7_with_init_storage$ 9 | } 10 | GETGLOB 6 11 | THROWIF 51 12 | ENDS 13 | .loc ../node_modules/@broxus/contracts/contracts/utils/CheckPubKey.tsol, 9 14 | GETGLOB 5 15 | DUP 16 | ISNULL 17 | PUSHCONT { 18 | DROP 19 | PUSHINT 0 20 | } 21 | IF 22 | GETGLOB 2 23 | EQUAL 24 | THROWIFNOT 1103 25 | .loc ../node_modules/@broxus/contracts/contracts/wallets/Account.tsol, 18 26 | ACCEPT 27 | .loc ../node_modules/@broxus/contracts/contracts/wallets/Account.tsol, 20 28 | GETGLOB 5 29 | DUP 30 | ISNULL 31 | PUSHCONT { 32 | DROP 33 | PUSHINT 0 34 | } 35 | IF 36 | CALLREF { 37 | CALL $setOwnership_3e1af783_internal_macro$ 38 | } 39 | .loc ../node_modules/@broxus/contracts/contracts/utils/CheckPubKey.tsol, 0 40 | CALLREF { 41 | CALL $c7_to_c4$ 42 | } 43 | THROW 0 44 | 45 | .macro sendTransaction 46 | DROP 47 | GETGLOB 6 48 | THROWIFNOT 76 49 | GETGLOB 2 50 | ISNULL 51 | IFREF { 52 | CALL $c4_to_c7$ 53 | } 54 | .loc ../node_modules/@broxus/contracts/contracts/wallets/Account.tsol, 31 55 | OVER 56 | PUSHCONT { 57 | LDREF 58 | ENDS 59 | CTOS 60 | } 61 | IF 62 | LDMSGADDR 63 | LDU 128 64 | LDI 1 65 | LDU 8 66 | LDREF 67 | ENDS 68 | .loc ../node_modules/@broxus/contracts/contracts/wallets/Account.tsol, 0 69 | CALLREF { 70 | CALL $sendTransaction_c96c9ed1_internal_macro$ 71 | } 72 | IFREF { 73 | CALL $upd_only_time_in_c4$ 74 | } 75 | THROW 0 76 | 77 | .globl sendTransaction_c96c9ed1_internal 78 | .type sendTransaction_c96c9ed1_internal, @function 79 | CALL $sendTransaction_c96c9ed1_internal_macro$ 80 | 81 | .macro sendTransaction_c96c9ed1_internal_macro 82 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 14 83 | GETGLOB 5 84 | DUP 85 | ISNULL 86 | PUSHCONT { 87 | DROP 88 | PUSHINT 0 89 | } 90 | IF 91 | GETGLOB 10 92 | EQUAL 93 | THROWIFNOT 1101 94 | .loc ../node_modules/@broxus/contracts/contracts/wallets/Account.tsol, 42 95 | ACCEPT 96 | .loc ../node_modules/@broxus/contracts/contracts/wallets/Account.tsol, 44 97 | ROLL 3 98 | BLKSWAP 2, 3 99 | NEWC 100 | STSLICECONST x6_ 101 | STI 1 102 | STSLICECONST x1_ 103 | STSLICE 104 | SWAP 105 | STGRAMS 106 | PUSHINT 1 107 | STUR 107 108 | STREF 109 | ENDC 110 | SWAP 111 | SENDRAWMSG 112 | .loc ../node_modules/@broxus/contracts/contracts/wallets/Account.tsol, 0 113 | 114 | .globl setOwnership_3e1af783_internal 115 | .type setOwnership_3e1af783_internal, @function 116 | CALL $setOwnership_3e1af783_internal_macro$ 117 | 118 | .macro setOwnership_3e1af783_internal_macro 119 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 23 120 | GETGLOB 10 121 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 25 122 | OVER 123 | SETGLOB 10 124 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 27 125 | PUSHSLICE xc0000000000000000000000000536cd3f2 126 | NEWC 127 | STSLICE 128 | STU 256 129 | STU 256 130 | ENDC 131 | PUSHINT 0 132 | SENDRAWMSG 133 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 0 134 | 135 | .macro transferOwnership 136 | DROP 137 | GETGLOB 6 138 | THROWIFNOT 76 139 | GETGLOB 2 140 | ISNULL 141 | IFREF { 142 | CALL $c4_to_c7$ 143 | } 144 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 33 145 | OVER 146 | PUSHCONT { 147 | LDREF 148 | ENDS 149 | CTOS 150 | } 151 | IF 152 | LDU 256 153 | ENDS 154 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 0 155 | CALLREF { 156 | CALL $transferOwnership_d23e8489_internal_macro$ 157 | } 158 | DROP 159 | CALLREF { 160 | CALL $c7_to_c4$ 161 | } 162 | THROW 0 163 | 164 | .macro transferOwnership_d23e8489_internal_macro 165 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 14 166 | GETGLOB 5 167 | DUP 168 | ISNULL 169 | PUSHCONT { 170 | DROP 171 | PUSHINT 0 172 | } 173 | IF 174 | GETGLOB 10 175 | EQUAL 176 | THROWIFNOT 1101 177 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 36 178 | DUP 179 | THROWIFNOT 1102 180 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 37 181 | ACCEPT 182 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 39 183 | CALLREF { 184 | CALL $setOwnership_3e1af783_internal_macro$ 185 | } 186 | .loc ../node_modules/@broxus/contracts/contracts/access/ExternalOwner.tsol, 0 187 | 188 | .macro c4_to_c7 189 | PUSHROOT 190 | CTOS 191 | LDU 256 ; pubkey c4 192 | LDU 64 ; pubkey timestamp c4 193 | LDU 1 ; ctor flag 194 | NIP 195 | LDU 256 196 | LDU 256 197 | ENDS 198 | SETGLOB 11 199 | SETGLOB 10 200 | SETGLOB 3 201 | SETGLOB 2 202 | 203 | .macro c4_to_c7_with_init_storage 204 | PUSHROOT 205 | CTOS 206 | SBITS 207 | GTINT 1 208 | PUSHCONT { 209 | PUSHINT 0 210 | PUSHROOT 211 | CTOS 212 | PLDDICT ; D 213 | PUSHINT 0 214 | PUSHINT 1 215 | PUSH S2 216 | PUSHINT 64 217 | DICTUGET 218 | ZEROSWAPIFNOT 219 | PUSHCONT { 220 | PLDU 256 221 | } 222 | IF 223 | SETGLOB 11 224 | SETGLOB 10 225 | PUSHINT 64 226 | DICTUGET 227 | THROWIFNOT 61 228 | PLDU 256 229 | SETGLOB 2 230 | PUSHINT 0 ; timestamp 231 | SETGLOB 3 232 | } 233 | IFREFELSE { 234 | CALL $c4_to_c7$ 235 | } 236 | 237 | .macro c7_to_c4 238 | GETGLOB 11 239 | GETGLOB 10 240 | GETGLOB 3 241 | GETGLOB 2 242 | NEWC 243 | STU 256 244 | STU 64 245 | STONE 246 | STU 256 247 | STU 256 248 | ENDC 249 | POPROOT 250 | 251 | .macro upd_only_time_in_c4 252 | PUSHROOT 253 | CTOS 254 | LDU 256 255 | LDU 64 256 | NIP 257 | GETGLOB 3 258 | ROT 259 | NEWC 260 | STU 256 261 | STU 64 262 | STSLICE 263 | ENDC 264 | POPROOT 265 | 266 | .internal-alias :main_internal, 0 267 | .internal :main_internal 268 | PUSHROOT 269 | CTOS 270 | SBITS 271 | NEQINT 1 272 | SETGLOB 6 273 | PUSH S2 274 | CTOS 275 | PLDU 4 276 | MODPOW2 1 277 | IFRET 278 | OVER 279 | SEMPTY ; isEmpty 280 | IFJMPREF { 281 | GETGLOB 6 282 | THROWIFNOT 76 283 | } 284 | OVER 285 | LDUQ 32 ; [funcId] body' ok 286 | THROWIFNOT 60 287 | OVER 288 | IFNOTJMPREF { 289 | GETGLOB 6 290 | THROWIFNOT 76 291 | } 292 | SWAP 293 | CALLREF { 294 | CALL $public_function_selector$ 295 | } 296 | THROW 60 297 | 298 | .internal-alias :main_external, -1 299 | .internal :main_external 300 | PUSHROOT 301 | CTOS 302 | SBITS 303 | NEQINT 1 304 | SETGLOB 6 305 | OVER 306 | CALLREF { 307 | CALL $c4_to_c7_with_init_storage$ 308 | } 309 | LDU 1 ; haveSign msgSlice 310 | SWAP 311 | PUSHCONT { 312 | PUSHPOW2 9 313 | LDSLICEX ; signatureSlice msgSlice 314 | DUP 315 | HASHSU ; signatureSlice msgSlice hashMsgSlice 316 | SWAP 317 | LDU 1 ; signatureSlice hashMsgSlice hasPubkey msgSlice 318 | SWAP 319 | PUSHCONT { 320 | LDU 256 ; signatureSlice hashMsgSlice pubkey msgSlice 321 | XCHG S3 322 | SWAP 323 | } 324 | PUSHCONT { 325 | XCHG S2 326 | GETGLOB 2 327 | } 328 | IFELSE 329 | DUP 330 | SETGLOB 5 331 | CHKSIGNU ; msgSlice isSigned 332 | THROWIFNOT 40 333 | } 334 | PUSHCONT { 335 | LDU 1 ; hasPubkey msgSlice 336 | SWAP 337 | THROWIF 58 338 | } 339 | IFELSE 340 | LDU 64 ; timestamp msgSlice 341 | SWAP 342 | CALL $replay_protection_macro$ 343 | LDU 32 ; expireAt msgSlice 344 | SWAP 345 | NOW ; msgSlice expireAt now 346 | GREATER ; msgSlice expireAt>now 347 | THROWIFNOT 57 348 | LDU 32 ; funcId body 349 | SWAP 350 | CALLREF { 351 | CALL $public_function_selector$ 352 | } 353 | THROW 60 354 | 355 | .macro owner 356 | DROP 357 | ENDS 358 | CALLREF { 359 | CALL $c4_to_c7$ 360 | } 361 | GETGLOB 10 362 | OVER 363 | PUSHCONT { 364 | PUSHSLICE xc00000000000000000000000009178e9bd 365 | NEWC 366 | STSLICE 367 | STU 256 368 | ENDC 369 | PUSHINT 0 370 | SENDRAWMSG 371 | } 372 | IF 373 | THROW 0 374 | 375 | .macro _randomNonce 376 | DROP 377 | ENDS 378 | CALLREF { 379 | CALL $c4_to_c7$ 380 | } 381 | GETGLOB 11 382 | OVER 383 | PUSHCONT { 384 | PUSHSLICE xc0000000000000000000000000bb53331f 385 | NEWC 386 | STSLICE 387 | STU 256 388 | ENDC 389 | PUSHINT 0 390 | SENDRAWMSG 391 | } 392 | IF 393 | THROW 0 394 | 395 | .macro public_function_selector 396 | DUP 397 | PUSHINT 1482330212 398 | LEQ 399 | IFJMPREF { 400 | DUP 401 | PUSHINT 293136829 402 | EQUAL 403 | IFJMPREF { 404 | CALL $owner$ 405 | } 406 | DUP 407 | PUSHINT 995308319 408 | EQUAL 409 | IFJMPREF { 410 | CALL $_randomNonce$ 411 | } 412 | DUP 413 | PUSHINT 1290691692 414 | EQUAL 415 | IFJMPREF { 416 | CALL $sendTransaction$ 417 | } 418 | DUP 419 | PUSHINT 1482330212 420 | EQUAL 421 | IFJMPREF { 422 | CALL $transferOwnership$ 423 | } 424 | } 425 | DUP 426 | PUSHINT 1756716863 427 | EQUAL 428 | IFJMPREF { 429 | CALL $constructor$ 430 | } 431 | 432 | -------------------------------------------------------------------------------- /test/contracts/build/Wallet.tvc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/venom-blockchain/vesting/47c022404231af7d4f309a3dc2c70ea5e9017501/test/contracts/build/Wallet.tvc -------------------------------------------------------------------------------- /test/utils/common.ts: -------------------------------------------------------------------------------- 1 | import { Token } from "./wrappers/token"; 2 | import { Address, Contract, getRandomNonce, toNano, WalletTypes, zeroAddress } from "locklift"; 3 | import { Account } from "locklift/everscale-client"; 4 | import Bignumber from "bignumber.js"; 5 | 6 | const logger = require("mocha-logger"); 7 | const { expect } = require("chai"); 8 | 9 | export const isValidEverAddress = (address: string) => /^(?:-1|0):[0-9a-fA-F]{64}$/.test(address); 10 | 11 | export async function sleep(ms = 1000) { 12 | return new Promise(resolve => setTimeout(resolve, ms)); 13 | } 14 | 15 | export async function tryIncreaseTime(seconds: number) { 16 | // @ts-ignore 17 | if (locklift.testing.isEnabled) { 18 | await locklift.testing.increaseTime(seconds); 19 | } else { 20 | await sleep(seconds * 1000); 21 | } 22 | } 23 | 24 | export function bn(num: number | string) { 25 | return new Bignumber(num); 26 | } 27 | 28 | // -------------------------- ENTITIES ---------------------------- 29 | 30 | export const setupTokenRoot = async function (token_name: string, token_symbol: string, owner: Account, decimals = 9) { 31 | const signer = await locklift.keystore.getSigner("0"); 32 | const TokenPlatform = await locklift.factory.getContractArtifacts("TokenWalletPlatform"); 33 | 34 | const TokenWallet = await locklift.factory.getContractArtifacts("TokenWalletUpgradeable"); 35 | const { contract: _root, tx } = await locklift.tracing.trace( 36 | locklift.factory.deployContract({ 37 | contract: "TokenRootUpgradeable", 38 | initParams: { 39 | name_: token_name, 40 | symbol_: token_symbol, 41 | decimals_: decimals, 42 | rootOwner_: owner.address, 43 | walletCode_: TokenWallet.code, 44 | randomNonce_: getRandomNonce(), 45 | deployer_: zeroAddress, 46 | platformCode_: TokenPlatform.code, 47 | }, 48 | publicKey: signer?.publicKey as string, 49 | constructorParams: { 50 | initialSupplyTo: zeroAddress, 51 | initialSupply: 0, 52 | deployWalletValue: 0, 53 | mintDisabled: false, 54 | burnByRootDisabled: false, 55 | burnPaused: false, 56 | remainingGasTo: owner.address, 57 | }, 58 | value: locklift.utils.toNano(2), 59 | }), 60 | ); 61 | 62 | logger.log(`Token root address: ${_root.address.toString()}`); 63 | 64 | expect(Number(await locklift.provider.getBalance(_root.address))).to.be.above(0, "Root balance empty"); 65 | return new Token(_root, owner); 66 | }; 67 | 68 | export const deployUser = async function (initial_balance = 100, user_name = "User"): Promise { 69 | const signer = await locklift.keystore.getSigner("0"); 70 | 71 | const { account: _user, tx } = await locklift.factory.accounts.addNewAccount({ 72 | type: WalletTypes.MsigAccount, 73 | mSigType: "SafeMultisig", 74 | contract: "Wallet", 75 | //Value which will send to the new account from a giver 76 | value: toNano(initial_balance), 77 | publicKey: signer?.publicKey as string, 78 | initParams: { 79 | _randomNonce: getRandomNonce(), 80 | }, 81 | constructorParams: {}, 82 | }); 83 | 84 | logger.log(`${user_name} address: ${_user.address.toString()}`); 85 | return _user; 86 | }; 87 | -------------------------------------------------------------------------------- /test/utils/indexer.ts: -------------------------------------------------------------------------------- 1 | import { Address, Contract } from "locklift"; 2 | import { FactorySource } from "../../build/factorySource"; 3 | import { bn } from "./common"; 4 | 5 | const { expect } = require("chai"); 6 | const logger = require("mocha-logger"); 7 | 8 | export async function getSaltedCodeHash( 9 | tvcCode: string, 10 | vestingFactory: Address, 11 | acc: Address, 12 | indexType: 0 | 1 | 2, 13 | vestingContractType: 0 | 1, 14 | ): Promise { 15 | const { hash: saltedCodeHash } = await locklift.provider.setCodeSalt({ 16 | code: tvcCode, 17 | salt: { 18 | structure: [ 19 | { name: "_vestingFactory", type: "address" }, 20 | { name: "_acc", type: "address" }, 21 | { name: "_indexType", type: "uint8" }, 22 | { name: "_vestingContractType", type: "uint8" }, 23 | ] as const, 24 | abiVersion: "2.1", 25 | data: { 26 | _vestingFactory: vestingFactory, 27 | _acc: acc, 28 | _indexType: indexType, 29 | _vestingContractType: vestingContractType, 30 | }, 31 | }, 32 | }); 33 | 34 | return "0x" + saltedCodeHash; 35 | } 36 | 37 | export async function validateIndexInfo( 38 | index: Address, 39 | expectedFactory: Address, 40 | expectedVestingContract: Address, 41 | expectedAccount: Address, 42 | ) { 43 | const indexContract = locklift.factory.getDeployedContract("Index", index); 44 | 45 | const info = await indexContract.methods.getInfo({ answerId: 0 }).call(); 46 | 47 | expect(info.acc.toString()).to.be.equal(expectedAccount.toString()); 48 | expect(info.vestingFactory.toString()).to.be.equal(expectedFactory.toString()); 49 | expect(info.vestingContract.toString()).to.be.equal(expectedVestingContract.toString()); 50 | } 51 | 52 | export async function validateIndexesAmount(indexCodeHash: string, expectedAmount: number): Promise { 53 | const indexes = (await locklift.provider.getAccountsByCodeHash({ codeHash: indexCodeHash })).accounts; 54 | 55 | expect(indexes.length).to.be.equal(expectedAmount); 56 | return indexes; 57 | } 58 | 59 | export async function validateIndexCodeHash( 60 | indexer: Contract, 61 | indexCode: string, 62 | factory: Address, 63 | acc: Address, 64 | indexType: 0 | 1 | 2, 65 | vestingContractType: 0 | 1, 66 | ) { 67 | const codeHash = await getSaltedCodeHash(indexCode, factory, acc, indexType, vestingContractType); 68 | const { codeHash: codeHashResolved } = await indexer.methods 69 | .resolveIndexCodeHash({ 70 | answerId: 0, 71 | acc: acc, 72 | indexType: indexType, 73 | vestingContractType: vestingContractType, 74 | }) 75 | .call(); 76 | 77 | expect(codeHash).to.be.eq("0x" + bn(codeHashResolved).toString(16).padStart(64, "0")); 78 | return codeHash; 79 | } 80 | export async function validateIndexAddress( 81 | indexer: Contract, 82 | expectedIndex: Address, 83 | vestingContract: Address, 84 | acc: Address, 85 | indexType: 0 | 1 | 2, 86 | vestingContractType: 0 | 1, 87 | ) { 88 | const { index: indexAddress } = await indexer.methods 89 | .resolveIndexAddress({ 90 | answerId: 0, 91 | acc: acc, 92 | indexType: indexType, 93 | vestingContractType: vestingContractType, 94 | vestingContract: vestingContract, 95 | }) 96 | .call(); 97 | 98 | expect(indexAddress.toString()).to.be.eq(expectedIndex.toString()); 99 | return indexAddress; 100 | } 101 | -------------------------------------------------------------------------------- /test/utils/wrappers/token.ts: -------------------------------------------------------------------------------- 1 | import {Address, Contract, toNano} from "locklift"; 2 | import {TokenWallet} from "./token_wallet"; 3 | import {FactorySource} from "../../../build/factorySource"; 4 | import {Account} from 'locklift/everscale-client' 5 | 6 | const logger = require("mocha-logger"); 7 | 8 | 9 | export class Token { 10 | public contract: Contract; 11 | public owner: Account; 12 | public address: Address; 13 | 14 | constructor(token_contract: Contract, token_owner: Account) { 15 | this.contract = token_contract; 16 | this.owner = token_owner; 17 | this.address = this.contract.address; 18 | } 19 | 20 | static async from_addr(addr: Address, owner: Account) { 21 | const contract = await locklift.factory.getDeployedContract('TokenRootUpgradeable', addr); 22 | return new Token(contract, owner); 23 | } 24 | 25 | async walletAddr(user: Address) { 26 | return (await this.contract.methods.walletOf({walletOwner: user, answerId: 0}).call()).value0; 27 | } 28 | 29 | async wallet(user: Account) { 30 | const wallet_addr = await this.walletAddr(user.address); 31 | return await TokenWallet.from_addr(wallet_addr, user); 32 | } 33 | 34 | async deployWallet(user: Account) { 35 | await this.contract.methods.deployWallet( 36 | {answerId: 0, walletOwner: user.address, deployWalletValue: toNano(1)} 37 | ).send({ 38 | amount: toNano(2), 39 | from: user.address 40 | }); 41 | 42 | const addr = await this.walletAddr(user.address); 43 | return await TokenWallet.from_addr(addr, user); 44 | } 45 | 46 | async transferOwnership(newOwner: Account) { 47 | await locklift.tracing.trace(this.contract.methods.transferOwnership({ 48 | newOwner: newOwner.address, 49 | remainingGasTo: this.owner.address, 50 | callbacks: [] 51 | }).send({ 52 | from: this.owner.address, 53 | amount: toNano(2) 54 | })); 55 | this.owner = newOwner; 56 | } 57 | 58 | async mint(mint_amount: any, user: Account) { 59 | await locklift.tracing.trace(this.contract.methods.mint({ 60 | amount: mint_amount, 61 | recipient: user.address, 62 | deployWalletValue: locklift.utils.toNano(1), 63 | remainingGasTo: this.owner.address, 64 | notify: false, 65 | payload: '' 66 | }).send({ 67 | amount: toNano(5), 68 | from: this.owner.address 69 | })); 70 | 71 | const walletAddr = await this.walletAddr(user.address); 72 | return await TokenWallet.from_addr(walletAddr, user); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /test/utils/wrappers/token_wallet.ts: -------------------------------------------------------------------------------- 1 | import { Address, Contract } from "locklift"; 2 | import { FactorySource } from "../../../build/factorySource"; 3 | import { Account } from "locklift/everscale-client"; 4 | const { toNano } = locklift.utils; 5 | 6 | export class TokenWallet { 7 | public contract: Contract; 8 | public _owner: Account | null; 9 | public address: Address; 10 | public name: string | undefined; 11 | 12 | constructor(wallet_contract: Contract, wallet_owner: Account | null) { 13 | this.contract = wallet_contract; 14 | this._owner = wallet_owner; 15 | this.address = this.contract.address; 16 | } 17 | 18 | static async from_addr(addr: Address, owner: Account | null) { 19 | const wallet = await locklift.factory.getDeployedContract("TokenWalletUpgradeable", addr); 20 | return new TokenWallet(wallet, owner); 21 | } 22 | 23 | async owner() { 24 | return await this.contract.methods.owner({ answerId: 0 }).call(); 25 | } 26 | 27 | async root() { 28 | return await this.contract.methods.root({ answerId: 0 }).call(); 29 | } 30 | 31 | async balance() { 32 | return (await this.contract.methods.balance({ answerId: 0 }).call()).value0; 33 | } 34 | 35 | async transfer(amount: number | string, receiver: Address, payload = "", value: any) { 36 | const owner = this._owner as Account; 37 | return await this.contract.methods 38 | .transfer({ 39 | amount: amount, 40 | recipient: receiver, 41 | deployWalletValue: 0, 42 | remainingGasTo: owner.address, 43 | notify: true, 44 | payload: payload, 45 | }) 46 | .send({ 47 | amount: value || toNano(5), 48 | from: owner.address, 49 | }); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */, 4 | "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, 5 | 6 | "strict": true /* Enable all strict type-checking options. */, 7 | "types": ["node", "mocha"] /* Type declaration files to be included in compilation. */, 8 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, 9 | 10 | "skipLibCheck": true /* Skip type checking of declaration files. */, 11 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ 12 | } 13 | } 14 | --------------------------------------------------------------------------------