clawcontract 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +222 -0
- package/dist/analyzer/fallback.d.ts +28 -0
- package/dist/analyzer/fallback.d.ts.map +1 -0
- package/dist/analyzer/fallback.js +142 -0
- package/dist/analyzer/fallback.js.map +1 -0
- package/dist/analyzer/index.d.ts +24 -0
- package/dist/analyzer/index.d.ts.map +1 -0
- package/dist/analyzer/index.js +73 -0
- package/dist/analyzer/index.js.map +1 -0
- package/dist/analyzer/slither.d.ts +36 -0
- package/dist/analyzer/slither.d.ts.map +1 -0
- package/dist/analyzer/slither.js +92 -0
- package/dist/analyzer/slither.js.map +1 -0
- package/dist/cli/commands/analyze.d.ts +7 -0
- package/dist/cli/commands/analyze.d.ts.map +1 -0
- package/dist/cli/commands/analyze.js +74 -0
- package/dist/cli/commands/analyze.js.map +1 -0
- package/dist/cli/commands/delete.d.ts +5 -0
- package/dist/cli/commands/delete.d.ts.map +1 -0
- package/dist/cli/commands/delete.js +48 -0
- package/dist/cli/commands/delete.js.map +1 -0
- package/dist/cli/commands/deploy.d.ts +5 -0
- package/dist/cli/commands/deploy.d.ts.map +1 -0
- package/dist/cli/commands/deploy.js +88 -0
- package/dist/cli/commands/deploy.js.map +1 -0
- package/dist/cli/commands/full.d.ts +5 -0
- package/dist/cli/commands/full.d.ts.map +1 -0
- package/dist/cli/commands/full.js +83 -0
- package/dist/cli/commands/full.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +5 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +35 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/interact.d.ts +6 -0
- package/dist/cli/commands/interact.d.ts.map +1 -0
- package/dist/cli/commands/interact.js +136 -0
- package/dist/cli/commands/interact.js.map +1 -0
- package/dist/cli/commands/list.d.ts +6 -0
- package/dist/cli/commands/list.d.ts.map +1 -0
- package/dist/cli/commands/list.js +37 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/setup.d.ts +8 -0
- package/dist/cli/commands/setup.d.ts.map +1 -0
- package/dist/cli/commands/setup.js +36 -0
- package/dist/cli/commands/setup.js.map +1 -0
- package/dist/cli/commands/verify.d.ts +9 -0
- package/dist/cli/commands/verify.d.ts.map +1 -0
- package/dist/cli/commands/verify.js +87 -0
- package/dist/cli/commands/verify.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +104 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/utils.d.ts +6 -0
- package/dist/cli/utils.d.ts.map +1 -0
- package/dist/cli/utils.js +29 -0
- package/dist/cli/utils.js.map +1 -0
- package/dist/config/chains.d.ts +18 -0
- package/dist/config/chains.d.ts.map +1 -0
- package/dist/config/chains.js +52 -0
- package/dist/config/chains.js.map +1 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +2 -0
- package/dist/config/index.js.map +1 -0
- package/dist/deployer/compiler.d.ts +10 -0
- package/dist/deployer/compiler.d.ts.map +1 -0
- package/dist/deployer/compiler.js +93 -0
- package/dist/deployer/compiler.js.map +1 -0
- package/dist/deployer/deploy.d.ts +28 -0
- package/dist/deployer/deploy.d.ts.map +1 -0
- package/dist/deployer/deploy.js +60 -0
- package/dist/deployer/deploy.js.map +1 -0
- package/dist/deployer/hardhat-config-template.d.ts +2 -0
- package/dist/deployer/hardhat-config-template.d.ts.map +1 -0
- package/dist/deployer/hardhat-config-template.js +20 -0
- package/dist/deployer/hardhat-config-template.js.map +1 -0
- package/dist/deployer/index.d.ts +7 -0
- package/dist/deployer/index.d.ts.map +1 -0
- package/dist/deployer/index.js +4 -0
- package/dist/deployer/index.js.map +1 -0
- package/dist/deployer/metadata.d.ts +16 -0
- package/dist/deployer/metadata.d.ts.map +1 -0
- package/dist/deployer/metadata.js +315 -0
- package/dist/deployer/metadata.js.map +1 -0
- package/dist/deployer/wallet.d.ts +6 -0
- package/dist/deployer/wallet.d.ts.map +1 -0
- package/dist/deployer/wallet.js +21 -0
- package/dist/deployer/wallet.js.map +1 -0
- package/dist/generator/index.d.ts +19 -0
- package/dist/generator/index.d.ts.map +1 -0
- package/dist/generator/index.js +33 -0
- package/dist/generator/index.js.map +1 -0
- package/dist/generator/llm.d.ts +10 -0
- package/dist/generator/llm.d.ts.map +1 -0
- package/dist/generator/llm.js +71 -0
- package/dist/generator/llm.js.map +1 -0
- package/dist/generator/templates/erc20.d.ts +2 -0
- package/dist/generator/templates/erc20.d.ts.map +1 -0
- package/dist/generator/templates/erc20.js +106 -0
- package/dist/generator/templates/erc20.js.map +1 -0
- package/dist/generator/templates/erc20.sol.d.ts +2 -0
- package/dist/generator/templates/erc20.sol.d.ts.map +1 -0
- package/dist/generator/templates/erc20.sol.js +106 -0
- package/dist/generator/templates/erc20.sol.js.map +1 -0
- package/dist/generator/templates/erc721.d.ts +2 -0
- package/dist/generator/templates/erc721.d.ts.map +1 -0
- package/dist/generator/templates/erc721.js +168 -0
- package/dist/generator/templates/erc721.js.map +1 -0
- package/dist/generator/templates/erc721.sol.d.ts +2 -0
- package/dist/generator/templates/erc721.sol.d.ts.map +1 -0
- package/dist/generator/templates/erc721.sol.js +168 -0
- package/dist/generator/templates/erc721.sol.js.map +1 -0
- package/dist/generator/templates/index.d.ts +21 -0
- package/dist/generator/templates/index.d.ts.map +1 -0
- package/dist/generator/templates/index.js +157 -0
- package/dist/generator/templates/index.js.map +1 -0
- package/dist/generator/templates/multisig.d.ts +2 -0
- package/dist/generator/templates/multisig.d.ts.map +1 -0
- package/dist/generator/templates/multisig.js +136 -0
- package/dist/generator/templates/multisig.js.map +1 -0
- package/dist/generator/templates/multisig.sol.d.ts +2 -0
- package/dist/generator/templates/multisig.sol.d.ts.map +1 -0
- package/dist/generator/templates/multisig.sol.js +136 -0
- package/dist/generator/templates/multisig.sol.js.map +1 -0
- package/dist/generator/templates/staking.d.ts +2 -0
- package/dist/generator/templates/staking.d.ts.map +1 -0
- package/dist/generator/templates/staking.js +119 -0
- package/dist/generator/templates/staking.js.map +1 -0
- package/dist/generator/templates/staking.sol.d.ts +2 -0
- package/dist/generator/templates/staking.sol.d.ts.map +1 -0
- package/dist/generator/templates/staking.sol.js +119 -0
- package/dist/generator/templates/staking.sol.js.map +1 -0
- package/dist/generator/templates/vesting.d.ts +2 -0
- package/dist/generator/templates/vesting.d.ts.map +1 -0
- package/dist/generator/templates/vesting.js +133 -0
- package/dist/generator/templates/vesting.js.map +1 -0
- package/dist/generator/templates/vesting.sol.d.ts +2 -0
- package/dist/generator/templates/vesting.sol.d.ts.map +1 -0
- package/dist/generator/templates/vesting.sol.js +133 -0
- package/dist/generator/templates/vesting.sol.js.map +1 -0
- package/dist/generator/utils.d.ts +5 -0
- package/dist/generator/utils.d.ts.map +1 -0
- package/dist/generator/utils.js +49 -0
- package/dist/generator/utils.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/verifier/explorer-api.d.ts +21 -0
- package/dist/verifier/explorer-api.d.ts.map +1 -0
- package/dist/verifier/explorer-api.js +92 -0
- package/dist/verifier/explorer-api.js.map +1 -0
- package/dist/verifier/index.d.ts +20 -0
- package/dist/verifier/index.d.ts.map +1 -0
- package/dist/verifier/index.js +31 -0
- package/dist/verifier/index.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const STAKING_TEMPLATE = "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\ncontract BNBStaking {\n address public owner;\n uint256 public rewardRate;\n uint256 public minStake;\n uint256 public totalStaked;\n\n struct StakeInfo {\n uint256 amount;\n uint256 stakedAt;\n uint256 rewardDebt;\n }\n\n mapping(address => StakeInfo) public stakes;\n\n event Staked(address indexed user, uint256 amount);\n event Unstaked(address indexed user, uint256 amount);\n event RewardClaimed(address indexed user, uint256 reward);\n event RewardsFunded(address indexed funder, uint256 amount);\n event RewardRateUpdated(uint256 oldRate, uint256 newRate);\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"Not owner\");\n _;\n }\n\n constructor() {\n owner = msg.sender;\n rewardRate = {{REWARD_RATE}};\n minStake = {{MIN_STAKE}};\n }\n\n function stake() external payable {\n require(msg.value >= minStake, \"Below minimum stake\");\n StakeInfo storage info = stakes[msg.sender];\n if (info.amount > 0) {\n uint256 pending = _pendingReward(msg.sender);\n if (pending > 0) {\n info.rewardDebt += pending;\n }\n }\n info.amount += msg.value;\n info.stakedAt = block.timestamp;\n totalStaked += msg.value;\n emit Staked(msg.sender, msg.value);\n }\n\n function unstake(uint256 amount) external {\n StakeInfo storage info = stakes[msg.sender];\n require(info.amount >= amount, \"Insufficient stake\");\n uint256 pending = _pendingReward(msg.sender) + info.rewardDebt;\n info.amount -= amount;\n info.stakedAt = block.timestamp;\n info.rewardDebt = 0;\n totalStaked -= amount;\n uint256 total = amount + pending;\n require(address(this).balance >= total, \"Insufficient contract balance\");\n (bool success, ) = payable(msg.sender).call{value: total}(\"\");\n require(success, \"Transfer failed\");\n emit Unstaked(msg.sender, amount);\n if (pending > 0) {\n emit RewardClaimed(msg.sender, pending);\n }\n }\n\n function claimReward() external {\n uint256 pending = _pendingReward(msg.sender) + stakes[msg.sender].rewardDebt;\n require(pending > 0, \"No rewards\");\n stakes[msg.sender].stakedAt = block.timestamp;\n stakes[msg.sender].rewardDebt = 0;\n require(address(this).balance >= pending, \"Insufficient contract balance\");\n (bool success, ) = payable(msg.sender).call{value: pending}(\"\");\n require(success, \"Transfer failed\");\n emit RewardClaimed(msg.sender, pending);\n }\n\n function pendingReward(address user) external view returns (uint256) {\n return _pendingReward(user) + stakes[user].rewardDebt;\n }\n\n function fundRewards() external payable onlyOwner {\n require(msg.value > 0, \"Must send BNB\");\n emit RewardsFunded(msg.sender, msg.value);\n }\n\n function setRewardRate(uint256 newRate) external onlyOwner {\n emit RewardRateUpdated(rewardRate, newRate);\n rewardRate = newRate;\n }\n\n function setMinStake(uint256 newMin) external onlyOwner {\n minStake = newMin;\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"New owner is zero address\");\n owner = newOwner;\n }\n\n function getStakeInfo(address user) external view returns (uint256 amount, uint256 stakedAt, uint256 pending) {\n StakeInfo storage info = stakes[user];\n return (info.amount, info.stakedAt, _pendingReward(user) + info.rewardDebt);\n }\n\n function _pendingReward(address user) internal view returns (uint256) {\n StakeInfo storage info = stakes[user];\n if (info.amount == 0) return 0;\n uint256 duration = block.timestamp - info.stakedAt;\n return (info.amount * rewardRate * duration) / (365 days * 10000);\n }\n\n receive() external payable {\n emit RewardsFunded(msg.sender, msg.value);\n }\n}\n";
|
|
2
|
+
//# sourceMappingURL=staking.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staking.d.ts","sourceRoot":"","sources":["../../../src/generator/templates/staking.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,+lIAqH5B,CAAC"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
export const STAKING_TEMPLATE = `// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.20;
|
|
3
|
+
|
|
4
|
+
contract BNBStaking {
|
|
5
|
+
address public owner;
|
|
6
|
+
uint256 public rewardRate;
|
|
7
|
+
uint256 public minStake;
|
|
8
|
+
uint256 public totalStaked;
|
|
9
|
+
|
|
10
|
+
struct StakeInfo {
|
|
11
|
+
uint256 amount;
|
|
12
|
+
uint256 stakedAt;
|
|
13
|
+
uint256 rewardDebt;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
mapping(address => StakeInfo) public stakes;
|
|
17
|
+
|
|
18
|
+
event Staked(address indexed user, uint256 amount);
|
|
19
|
+
event Unstaked(address indexed user, uint256 amount);
|
|
20
|
+
event RewardClaimed(address indexed user, uint256 reward);
|
|
21
|
+
event RewardsFunded(address indexed funder, uint256 amount);
|
|
22
|
+
event RewardRateUpdated(uint256 oldRate, uint256 newRate);
|
|
23
|
+
|
|
24
|
+
modifier onlyOwner() {
|
|
25
|
+
require(msg.sender == owner, "Not owner");
|
|
26
|
+
_;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
constructor() {
|
|
30
|
+
owner = msg.sender;
|
|
31
|
+
rewardRate = {{REWARD_RATE}};
|
|
32
|
+
minStake = {{MIN_STAKE}};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function stake() external payable {
|
|
36
|
+
require(msg.value >= minStake, "Below minimum stake");
|
|
37
|
+
StakeInfo storage info = stakes[msg.sender];
|
|
38
|
+
if (info.amount > 0) {
|
|
39
|
+
uint256 pending = _pendingReward(msg.sender);
|
|
40
|
+
if (pending > 0) {
|
|
41
|
+
info.rewardDebt += pending;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
info.amount += msg.value;
|
|
45
|
+
info.stakedAt = block.timestamp;
|
|
46
|
+
totalStaked += msg.value;
|
|
47
|
+
emit Staked(msg.sender, msg.value);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function unstake(uint256 amount) external {
|
|
51
|
+
StakeInfo storage info = stakes[msg.sender];
|
|
52
|
+
require(info.amount >= amount, "Insufficient stake");
|
|
53
|
+
uint256 pending = _pendingReward(msg.sender) + info.rewardDebt;
|
|
54
|
+
info.amount -= amount;
|
|
55
|
+
info.stakedAt = block.timestamp;
|
|
56
|
+
info.rewardDebt = 0;
|
|
57
|
+
totalStaked -= amount;
|
|
58
|
+
uint256 total = amount + pending;
|
|
59
|
+
require(address(this).balance >= total, "Insufficient contract balance");
|
|
60
|
+
(bool success, ) = payable(msg.sender).call{value: total}("");
|
|
61
|
+
require(success, "Transfer failed");
|
|
62
|
+
emit Unstaked(msg.sender, amount);
|
|
63
|
+
if (pending > 0) {
|
|
64
|
+
emit RewardClaimed(msg.sender, pending);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function claimReward() external {
|
|
69
|
+
uint256 pending = _pendingReward(msg.sender) + stakes[msg.sender].rewardDebt;
|
|
70
|
+
require(pending > 0, "No rewards");
|
|
71
|
+
stakes[msg.sender].stakedAt = block.timestamp;
|
|
72
|
+
stakes[msg.sender].rewardDebt = 0;
|
|
73
|
+
require(address(this).balance >= pending, "Insufficient contract balance");
|
|
74
|
+
(bool success, ) = payable(msg.sender).call{value: pending}("");
|
|
75
|
+
require(success, "Transfer failed");
|
|
76
|
+
emit RewardClaimed(msg.sender, pending);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function pendingReward(address user) external view returns (uint256) {
|
|
80
|
+
return _pendingReward(user) + stakes[user].rewardDebt;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function fundRewards() external payable onlyOwner {
|
|
84
|
+
require(msg.value > 0, "Must send BNB");
|
|
85
|
+
emit RewardsFunded(msg.sender, msg.value);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function setRewardRate(uint256 newRate) external onlyOwner {
|
|
89
|
+
emit RewardRateUpdated(rewardRate, newRate);
|
|
90
|
+
rewardRate = newRate;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function setMinStake(uint256 newMin) external onlyOwner {
|
|
94
|
+
minStake = newMin;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function transferOwnership(address newOwner) external onlyOwner {
|
|
98
|
+
require(newOwner != address(0), "New owner is zero address");
|
|
99
|
+
owner = newOwner;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function getStakeInfo(address user) external view returns (uint256 amount, uint256 stakedAt, uint256 pending) {
|
|
103
|
+
StakeInfo storage info = stakes[user];
|
|
104
|
+
return (info.amount, info.stakedAt, _pendingReward(user) + info.rewardDebt);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function _pendingReward(address user) internal view returns (uint256) {
|
|
108
|
+
StakeInfo storage info = stakes[user];
|
|
109
|
+
if (info.amount == 0) return 0;
|
|
110
|
+
uint256 duration = block.timestamp - info.stakedAt;
|
|
111
|
+
return (info.amount * rewardRate * duration) / (365 days * 10000);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
receive() external payable {
|
|
115
|
+
emit RewardsFunded(msg.sender, msg.value);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
`;
|
|
119
|
+
//# sourceMappingURL=staking.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staking.js","sourceRoot":"","sources":["../../../src/generator/templates/staking.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqH/B,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const STAKING_TEMPLATE = "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\ncontract BNBStaking {\n address public owner;\n uint256 public rewardRate;\n uint256 public minStake;\n uint256 public totalStaked;\n\n struct StakeInfo {\n uint256 amount;\n uint256 stakedAt;\n uint256 rewardDebt;\n }\n\n mapping(address => StakeInfo) public stakes;\n\n event Staked(address indexed user, uint256 amount);\n event Unstaked(address indexed user, uint256 amount);\n event RewardClaimed(address indexed user, uint256 reward);\n event RewardsFunded(address indexed funder, uint256 amount);\n event RewardRateUpdated(uint256 oldRate, uint256 newRate);\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"Not owner\");\n _;\n }\n\n constructor() {\n owner = msg.sender;\n rewardRate = {{REWARD_RATE}};\n minStake = {{MIN_STAKE}};\n }\n\n function stake() external payable {\n require(msg.value >= minStake, \"Below minimum stake\");\n StakeInfo storage info = stakes[msg.sender];\n if (info.amount > 0) {\n uint256 pending = _pendingReward(msg.sender);\n if (pending > 0) {\n info.rewardDebt += pending;\n }\n }\n info.amount += msg.value;\n info.stakedAt = block.timestamp;\n totalStaked += msg.value;\n emit Staked(msg.sender, msg.value);\n }\n\n function unstake(uint256 amount) external {\n StakeInfo storage info = stakes[msg.sender];\n require(info.amount >= amount, \"Insufficient stake\");\n uint256 pending = _pendingReward(msg.sender) + info.rewardDebt;\n info.amount -= amount;\n info.stakedAt = block.timestamp;\n info.rewardDebt = 0;\n totalStaked -= amount;\n uint256 total = amount + pending;\n require(address(this).balance >= total, \"Insufficient contract balance\");\n (bool success, ) = payable(msg.sender).call{value: total}(\"\");\n require(success, \"Transfer failed\");\n emit Unstaked(msg.sender, amount);\n if (pending > 0) {\n emit RewardClaimed(msg.sender, pending);\n }\n }\n\n function claimReward() external {\n uint256 pending = _pendingReward(msg.sender) + stakes[msg.sender].rewardDebt;\n require(pending > 0, \"No rewards\");\n stakes[msg.sender].stakedAt = block.timestamp;\n stakes[msg.sender].rewardDebt = 0;\n require(address(this).balance >= pending, \"Insufficient contract balance\");\n (bool success, ) = payable(msg.sender).call{value: pending}(\"\");\n require(success, \"Transfer failed\");\n emit RewardClaimed(msg.sender, pending);\n }\n\n function pendingReward(address user) external view returns (uint256) {\n return _pendingReward(user) + stakes[user].rewardDebt;\n }\n\n function fundRewards() external payable onlyOwner {\n require(msg.value > 0, \"Must send BNB\");\n emit RewardsFunded(msg.sender, msg.value);\n }\n\n function setRewardRate(uint256 newRate) external onlyOwner {\n emit RewardRateUpdated(rewardRate, newRate);\n rewardRate = newRate;\n }\n\n function setMinStake(uint256 newMin) external onlyOwner {\n minStake = newMin;\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"New owner is zero address\");\n owner = newOwner;\n }\n\n function getStakeInfo(address user) external view returns (uint256 amount, uint256 stakedAt, uint256 pending) {\n StakeInfo storage info = stakes[user];\n return (info.amount, info.stakedAt, _pendingReward(user) + info.rewardDebt);\n }\n\n function _pendingReward(address user) internal view returns (uint256) {\n StakeInfo storage info = stakes[user];\n if (info.amount == 0) return 0;\n uint256 duration = block.timestamp - info.stakedAt;\n return (info.amount * rewardRate * duration) / (365 days * 10000);\n }\n\n receive() external payable {\n emit RewardsFunded(msg.sender, msg.value);\n }\n}\n";
|
|
2
|
+
//# sourceMappingURL=staking.sol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staking.sol.d.ts","sourceRoot":"","sources":["../../../src/generator/templates/staking.sol.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,+lIAqH5B,CAAC"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
export const STAKING_TEMPLATE = `// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.20;
|
|
3
|
+
|
|
4
|
+
contract BNBStaking {
|
|
5
|
+
address public owner;
|
|
6
|
+
uint256 public rewardRate;
|
|
7
|
+
uint256 public minStake;
|
|
8
|
+
uint256 public totalStaked;
|
|
9
|
+
|
|
10
|
+
struct StakeInfo {
|
|
11
|
+
uint256 amount;
|
|
12
|
+
uint256 stakedAt;
|
|
13
|
+
uint256 rewardDebt;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
mapping(address => StakeInfo) public stakes;
|
|
17
|
+
|
|
18
|
+
event Staked(address indexed user, uint256 amount);
|
|
19
|
+
event Unstaked(address indexed user, uint256 amount);
|
|
20
|
+
event RewardClaimed(address indexed user, uint256 reward);
|
|
21
|
+
event RewardsFunded(address indexed funder, uint256 amount);
|
|
22
|
+
event RewardRateUpdated(uint256 oldRate, uint256 newRate);
|
|
23
|
+
|
|
24
|
+
modifier onlyOwner() {
|
|
25
|
+
require(msg.sender == owner, "Not owner");
|
|
26
|
+
_;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
constructor() {
|
|
30
|
+
owner = msg.sender;
|
|
31
|
+
rewardRate = {{REWARD_RATE}};
|
|
32
|
+
minStake = {{MIN_STAKE}};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function stake() external payable {
|
|
36
|
+
require(msg.value >= minStake, "Below minimum stake");
|
|
37
|
+
StakeInfo storage info = stakes[msg.sender];
|
|
38
|
+
if (info.amount > 0) {
|
|
39
|
+
uint256 pending = _pendingReward(msg.sender);
|
|
40
|
+
if (pending > 0) {
|
|
41
|
+
info.rewardDebt += pending;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
info.amount += msg.value;
|
|
45
|
+
info.stakedAt = block.timestamp;
|
|
46
|
+
totalStaked += msg.value;
|
|
47
|
+
emit Staked(msg.sender, msg.value);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function unstake(uint256 amount) external {
|
|
51
|
+
StakeInfo storage info = stakes[msg.sender];
|
|
52
|
+
require(info.amount >= amount, "Insufficient stake");
|
|
53
|
+
uint256 pending = _pendingReward(msg.sender) + info.rewardDebt;
|
|
54
|
+
info.amount -= amount;
|
|
55
|
+
info.stakedAt = block.timestamp;
|
|
56
|
+
info.rewardDebt = 0;
|
|
57
|
+
totalStaked -= amount;
|
|
58
|
+
uint256 total = amount + pending;
|
|
59
|
+
require(address(this).balance >= total, "Insufficient contract balance");
|
|
60
|
+
(bool success, ) = payable(msg.sender).call{value: total}("");
|
|
61
|
+
require(success, "Transfer failed");
|
|
62
|
+
emit Unstaked(msg.sender, amount);
|
|
63
|
+
if (pending > 0) {
|
|
64
|
+
emit RewardClaimed(msg.sender, pending);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function claimReward() external {
|
|
69
|
+
uint256 pending = _pendingReward(msg.sender) + stakes[msg.sender].rewardDebt;
|
|
70
|
+
require(pending > 0, "No rewards");
|
|
71
|
+
stakes[msg.sender].stakedAt = block.timestamp;
|
|
72
|
+
stakes[msg.sender].rewardDebt = 0;
|
|
73
|
+
require(address(this).balance >= pending, "Insufficient contract balance");
|
|
74
|
+
(bool success, ) = payable(msg.sender).call{value: pending}("");
|
|
75
|
+
require(success, "Transfer failed");
|
|
76
|
+
emit RewardClaimed(msg.sender, pending);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function pendingReward(address user) external view returns (uint256) {
|
|
80
|
+
return _pendingReward(user) + stakes[user].rewardDebt;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function fundRewards() external payable onlyOwner {
|
|
84
|
+
require(msg.value > 0, "Must send BNB");
|
|
85
|
+
emit RewardsFunded(msg.sender, msg.value);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function setRewardRate(uint256 newRate) external onlyOwner {
|
|
89
|
+
emit RewardRateUpdated(rewardRate, newRate);
|
|
90
|
+
rewardRate = newRate;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function setMinStake(uint256 newMin) external onlyOwner {
|
|
94
|
+
minStake = newMin;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function transferOwnership(address newOwner) external onlyOwner {
|
|
98
|
+
require(newOwner != address(0), "New owner is zero address");
|
|
99
|
+
owner = newOwner;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function getStakeInfo(address user) external view returns (uint256 amount, uint256 stakedAt, uint256 pending) {
|
|
103
|
+
StakeInfo storage info = stakes[user];
|
|
104
|
+
return (info.amount, info.stakedAt, _pendingReward(user) + info.rewardDebt);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function _pendingReward(address user) internal view returns (uint256) {
|
|
108
|
+
StakeInfo storage info = stakes[user];
|
|
109
|
+
if (info.amount == 0) return 0;
|
|
110
|
+
uint256 duration = block.timestamp - info.stakedAt;
|
|
111
|
+
return (info.amount * rewardRate * duration) / (365 days * 10000);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
receive() external payable {
|
|
115
|
+
emit RewardsFunded(msg.sender, msg.value);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
`;
|
|
119
|
+
//# sourceMappingURL=staking.sol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staking.sol.js","sourceRoot":"","sources":["../../../src/generator/templates/staking.sol.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqH/B,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const VESTING_TEMPLATE = "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\ninterface IERC20 {\n function transfer(address to, uint256 amount) external returns (bool);\n function balanceOf(address account) external view returns (uint256);\n}\n\ncontract TokenVesting {\n address public owner;\n IERC20 public token;\n address public beneficiary;\n uint256 public cliffDuration;\n uint256 public vestingDuration;\n uint256 public start;\n uint256 public totalAmount;\n uint256 public released;\n bool public revocable;\n bool public revoked;\n\n event TokensReleased(uint256 amount);\n event VestingRevoked(uint256 unreleased);\n event BeneficiaryUpdated(address indexed oldBeneficiary, address indexed newBeneficiary);\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"Not owner\");\n _;\n }\n\n modifier onlyBeneficiary() {\n require(msg.sender == beneficiary, \"Not beneficiary\");\n _;\n }\n\n constructor() {\n owner = msg.sender;\n token = IERC20({{TOKEN_ADDRESS}});\n beneficiary = {{BENEFICIARY}};\n cliffDuration = {{CLIFF_DURATION}};\n vestingDuration = {{VESTING_DURATION}};\n revocable = true;\n start = block.timestamp;\n }\n\n function initialize(uint256 amount) external onlyOwner {\n require(totalAmount == 0, \"Already initialized\");\n require(amount > 0, \"Amount must be > 0\");\n totalAmount = amount;\n }\n\n function release() external onlyBeneficiary {\n require(!revoked, \"Vesting revoked\");\n uint256 releasable = _releasableAmount();\n require(releasable > 0, \"No tokens to release\");\n released += releasable;\n require(token.transfer(beneficiary, releasable), \"Transfer failed\");\n emit TokensReleased(releasable);\n }\n\n function revoke() external onlyOwner {\n require(revocable, \"Not revocable\");\n require(!revoked, \"Already revoked\");\n uint256 releasable = _releasableAmount();\n if (releasable > 0) {\n released += releasable;\n require(token.transfer(beneficiary, releasable), \"Transfer failed\");\n emit TokensReleased(releasable);\n }\n uint256 unreleased = totalAmount - released;\n revoked = true;\n if (unreleased > 0) {\n require(token.transfer(owner, unreleased), \"Transfer failed\");\n }\n emit VestingRevoked(unreleased);\n }\n\n function releasableAmount() external view returns (uint256) {\n return _releasableAmount();\n }\n\n function vestedAmount() external view returns (uint256) {\n return _vestedAmount();\n }\n\n function updateBeneficiary(address newBeneficiary) external onlyOwner {\n require(newBeneficiary != address(0), \"Zero address\");\n require(!revoked, \"Vesting revoked\");\n emit BeneficiaryUpdated(beneficiary, newBeneficiary);\n beneficiary = newBeneficiary;\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"New owner is zero address\");\n owner = newOwner;\n }\n\n function vestingSchedule() external view returns (\n uint256 _start,\n uint256 _cliff,\n uint256 _duration,\n uint256 _total,\n uint256 _released,\n uint256 _releasable,\n bool _revoked\n ) {\n return (\n start,\n start + cliffDuration,\n vestingDuration,\n totalAmount,\n released,\n _releasableAmount(),\n revoked\n );\n }\n\n function _releasableAmount() internal view returns (uint256) {\n return _vestedAmount() - released;\n }\n\n function _vestedAmount() internal view returns (uint256) {\n if (block.timestamp < start + cliffDuration) {\n return 0;\n }\n uint256 elapsed = block.timestamp - start;\n if (elapsed >= vestingDuration) {\n return totalAmount;\n }\n return (totalAmount * elapsed) / vestingDuration;\n }\n}\n";
|
|
2
|
+
//# sourceMappingURL=vesting.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vesting.d.ts","sourceRoot":"","sources":["../../../src/generator/templates/vesting.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,wlIAmI5B,CAAC"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
export const VESTING_TEMPLATE = `// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.20;
|
|
3
|
+
|
|
4
|
+
interface IERC20 {
|
|
5
|
+
function transfer(address to, uint256 amount) external returns (bool);
|
|
6
|
+
function balanceOf(address account) external view returns (uint256);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
contract TokenVesting {
|
|
10
|
+
address public owner;
|
|
11
|
+
IERC20 public token;
|
|
12
|
+
address public beneficiary;
|
|
13
|
+
uint256 public cliffDuration;
|
|
14
|
+
uint256 public vestingDuration;
|
|
15
|
+
uint256 public start;
|
|
16
|
+
uint256 public totalAmount;
|
|
17
|
+
uint256 public released;
|
|
18
|
+
bool public revocable;
|
|
19
|
+
bool public revoked;
|
|
20
|
+
|
|
21
|
+
event TokensReleased(uint256 amount);
|
|
22
|
+
event VestingRevoked(uint256 unreleased);
|
|
23
|
+
event BeneficiaryUpdated(address indexed oldBeneficiary, address indexed newBeneficiary);
|
|
24
|
+
|
|
25
|
+
modifier onlyOwner() {
|
|
26
|
+
require(msg.sender == owner, "Not owner");
|
|
27
|
+
_;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
modifier onlyBeneficiary() {
|
|
31
|
+
require(msg.sender == beneficiary, "Not beneficiary");
|
|
32
|
+
_;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
constructor() {
|
|
36
|
+
owner = msg.sender;
|
|
37
|
+
token = IERC20({{TOKEN_ADDRESS}});
|
|
38
|
+
beneficiary = {{BENEFICIARY}};
|
|
39
|
+
cliffDuration = {{CLIFF_DURATION}};
|
|
40
|
+
vestingDuration = {{VESTING_DURATION}};
|
|
41
|
+
revocable = true;
|
|
42
|
+
start = block.timestamp;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function initialize(uint256 amount) external onlyOwner {
|
|
46
|
+
require(totalAmount == 0, "Already initialized");
|
|
47
|
+
require(amount > 0, "Amount must be > 0");
|
|
48
|
+
totalAmount = amount;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function release() external onlyBeneficiary {
|
|
52
|
+
require(!revoked, "Vesting revoked");
|
|
53
|
+
uint256 releasable = _releasableAmount();
|
|
54
|
+
require(releasable > 0, "No tokens to release");
|
|
55
|
+
released += releasable;
|
|
56
|
+
require(token.transfer(beneficiary, releasable), "Transfer failed");
|
|
57
|
+
emit TokensReleased(releasable);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function revoke() external onlyOwner {
|
|
61
|
+
require(revocable, "Not revocable");
|
|
62
|
+
require(!revoked, "Already revoked");
|
|
63
|
+
uint256 releasable = _releasableAmount();
|
|
64
|
+
if (releasable > 0) {
|
|
65
|
+
released += releasable;
|
|
66
|
+
require(token.transfer(beneficiary, releasable), "Transfer failed");
|
|
67
|
+
emit TokensReleased(releasable);
|
|
68
|
+
}
|
|
69
|
+
uint256 unreleased = totalAmount - released;
|
|
70
|
+
revoked = true;
|
|
71
|
+
if (unreleased > 0) {
|
|
72
|
+
require(token.transfer(owner, unreleased), "Transfer failed");
|
|
73
|
+
}
|
|
74
|
+
emit VestingRevoked(unreleased);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function releasableAmount() external view returns (uint256) {
|
|
78
|
+
return _releasableAmount();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function vestedAmount() external view returns (uint256) {
|
|
82
|
+
return _vestedAmount();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function updateBeneficiary(address newBeneficiary) external onlyOwner {
|
|
86
|
+
require(newBeneficiary != address(0), "Zero address");
|
|
87
|
+
require(!revoked, "Vesting revoked");
|
|
88
|
+
emit BeneficiaryUpdated(beneficiary, newBeneficiary);
|
|
89
|
+
beneficiary = newBeneficiary;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function transferOwnership(address newOwner) external onlyOwner {
|
|
93
|
+
require(newOwner != address(0), "New owner is zero address");
|
|
94
|
+
owner = newOwner;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function vestingSchedule() external view returns (
|
|
98
|
+
uint256 _start,
|
|
99
|
+
uint256 _cliff,
|
|
100
|
+
uint256 _duration,
|
|
101
|
+
uint256 _total,
|
|
102
|
+
uint256 _released,
|
|
103
|
+
uint256 _releasable,
|
|
104
|
+
bool _revoked
|
|
105
|
+
) {
|
|
106
|
+
return (
|
|
107
|
+
start,
|
|
108
|
+
start + cliffDuration,
|
|
109
|
+
vestingDuration,
|
|
110
|
+
totalAmount,
|
|
111
|
+
released,
|
|
112
|
+
_releasableAmount(),
|
|
113
|
+
revoked
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function _releasableAmount() internal view returns (uint256) {
|
|
118
|
+
return _vestedAmount() - released;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function _vestedAmount() internal view returns (uint256) {
|
|
122
|
+
if (block.timestamp < start + cliffDuration) {
|
|
123
|
+
return 0;
|
|
124
|
+
}
|
|
125
|
+
uint256 elapsed = block.timestamp - start;
|
|
126
|
+
if (elapsed >= vestingDuration) {
|
|
127
|
+
return totalAmount;
|
|
128
|
+
}
|
|
129
|
+
return (totalAmount * elapsed) / vestingDuration;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
`;
|
|
133
|
+
//# sourceMappingURL=vesting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vesting.js","sourceRoot":"","sources":["../../../src/generator/templates/vesting.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmI/B,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const VESTING_TEMPLATE = "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\ninterface IERC20 {\n function transfer(address to, uint256 amount) external returns (bool);\n function balanceOf(address account) external view returns (uint256);\n}\n\ncontract TokenVesting {\n address public owner;\n IERC20 public token;\n address public beneficiary;\n uint256 public cliffDuration;\n uint256 public vestingDuration;\n uint256 public start;\n uint256 public totalAmount;\n uint256 public released;\n bool public revocable;\n bool public revoked;\n\n event TokensReleased(uint256 amount);\n event VestingRevoked(uint256 unreleased);\n event BeneficiaryUpdated(address indexed oldBeneficiary, address indexed newBeneficiary);\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"Not owner\");\n _;\n }\n\n modifier onlyBeneficiary() {\n require(msg.sender == beneficiary, \"Not beneficiary\");\n _;\n }\n\n constructor() {\n owner = msg.sender;\n token = IERC20({{TOKEN_ADDRESS}});\n beneficiary = {{BENEFICIARY}};\n cliffDuration = {{CLIFF_DURATION}};\n vestingDuration = {{VESTING_DURATION}};\n revocable = true;\n start = block.timestamp;\n }\n\n function initialize(uint256 amount) external onlyOwner {\n require(totalAmount == 0, \"Already initialized\");\n require(amount > 0, \"Amount must be > 0\");\n totalAmount = amount;\n }\n\n function release() external onlyBeneficiary {\n require(!revoked, \"Vesting revoked\");\n uint256 releasable = _releasableAmount();\n require(releasable > 0, \"No tokens to release\");\n released += releasable;\n require(token.transfer(beneficiary, releasable), \"Transfer failed\");\n emit TokensReleased(releasable);\n }\n\n function revoke() external onlyOwner {\n require(revocable, \"Not revocable\");\n require(!revoked, \"Already revoked\");\n uint256 releasable = _releasableAmount();\n if (releasable > 0) {\n released += releasable;\n require(token.transfer(beneficiary, releasable), \"Transfer failed\");\n emit TokensReleased(releasable);\n }\n uint256 unreleased = totalAmount - released;\n revoked = true;\n if (unreleased > 0) {\n require(token.transfer(owner, unreleased), \"Transfer failed\");\n }\n emit VestingRevoked(unreleased);\n }\n\n function releasableAmount() external view returns (uint256) {\n return _releasableAmount();\n }\n\n function vestedAmount() external view returns (uint256) {\n return _vestedAmount();\n }\n\n function updateBeneficiary(address newBeneficiary) external onlyOwner {\n require(newBeneficiary != address(0), \"Zero address\");\n require(!revoked, \"Vesting revoked\");\n emit BeneficiaryUpdated(beneficiary, newBeneficiary);\n beneficiary = newBeneficiary;\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"New owner is zero address\");\n owner = newOwner;\n }\n\n function vestingSchedule() external view returns (\n uint256 _start,\n uint256 _cliff,\n uint256 _duration,\n uint256 _total,\n uint256 _released,\n uint256 _releasable,\n bool _revoked\n ) {\n return (\n start,\n start + cliffDuration,\n vestingDuration,\n totalAmount,\n released,\n _releasableAmount(),\n revoked\n );\n }\n\n function _releasableAmount() internal view returns (uint256) {\n return _vestedAmount() - released;\n }\n\n function _vestedAmount() internal view returns (uint256) {\n if (block.timestamp < start + cliffDuration) {\n return 0;\n }\n uint256 elapsed = block.timestamp - start;\n if (elapsed >= vestingDuration) {\n return totalAmount;\n }\n return (totalAmount * elapsed) / vestingDuration;\n }\n}\n";
|
|
2
|
+
//# sourceMappingURL=vesting.sol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vesting.sol.d.ts","sourceRoot":"","sources":["../../../src/generator/templates/vesting.sol.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,wlIAmI5B,CAAC"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
export const VESTING_TEMPLATE = `// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.20;
|
|
3
|
+
|
|
4
|
+
interface IERC20 {
|
|
5
|
+
function transfer(address to, uint256 amount) external returns (bool);
|
|
6
|
+
function balanceOf(address account) external view returns (uint256);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
contract TokenVesting {
|
|
10
|
+
address public owner;
|
|
11
|
+
IERC20 public token;
|
|
12
|
+
address public beneficiary;
|
|
13
|
+
uint256 public cliffDuration;
|
|
14
|
+
uint256 public vestingDuration;
|
|
15
|
+
uint256 public start;
|
|
16
|
+
uint256 public totalAmount;
|
|
17
|
+
uint256 public released;
|
|
18
|
+
bool public revocable;
|
|
19
|
+
bool public revoked;
|
|
20
|
+
|
|
21
|
+
event TokensReleased(uint256 amount);
|
|
22
|
+
event VestingRevoked(uint256 unreleased);
|
|
23
|
+
event BeneficiaryUpdated(address indexed oldBeneficiary, address indexed newBeneficiary);
|
|
24
|
+
|
|
25
|
+
modifier onlyOwner() {
|
|
26
|
+
require(msg.sender == owner, "Not owner");
|
|
27
|
+
_;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
modifier onlyBeneficiary() {
|
|
31
|
+
require(msg.sender == beneficiary, "Not beneficiary");
|
|
32
|
+
_;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
constructor() {
|
|
36
|
+
owner = msg.sender;
|
|
37
|
+
token = IERC20({{TOKEN_ADDRESS}});
|
|
38
|
+
beneficiary = {{BENEFICIARY}};
|
|
39
|
+
cliffDuration = {{CLIFF_DURATION}};
|
|
40
|
+
vestingDuration = {{VESTING_DURATION}};
|
|
41
|
+
revocable = true;
|
|
42
|
+
start = block.timestamp;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function initialize(uint256 amount) external onlyOwner {
|
|
46
|
+
require(totalAmount == 0, "Already initialized");
|
|
47
|
+
require(amount > 0, "Amount must be > 0");
|
|
48
|
+
totalAmount = amount;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function release() external onlyBeneficiary {
|
|
52
|
+
require(!revoked, "Vesting revoked");
|
|
53
|
+
uint256 releasable = _releasableAmount();
|
|
54
|
+
require(releasable > 0, "No tokens to release");
|
|
55
|
+
released += releasable;
|
|
56
|
+
require(token.transfer(beneficiary, releasable), "Transfer failed");
|
|
57
|
+
emit TokensReleased(releasable);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function revoke() external onlyOwner {
|
|
61
|
+
require(revocable, "Not revocable");
|
|
62
|
+
require(!revoked, "Already revoked");
|
|
63
|
+
uint256 releasable = _releasableAmount();
|
|
64
|
+
if (releasable > 0) {
|
|
65
|
+
released += releasable;
|
|
66
|
+
require(token.transfer(beneficiary, releasable), "Transfer failed");
|
|
67
|
+
emit TokensReleased(releasable);
|
|
68
|
+
}
|
|
69
|
+
uint256 unreleased = totalAmount - released;
|
|
70
|
+
revoked = true;
|
|
71
|
+
if (unreleased > 0) {
|
|
72
|
+
require(token.transfer(owner, unreleased), "Transfer failed");
|
|
73
|
+
}
|
|
74
|
+
emit VestingRevoked(unreleased);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function releasableAmount() external view returns (uint256) {
|
|
78
|
+
return _releasableAmount();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function vestedAmount() external view returns (uint256) {
|
|
82
|
+
return _vestedAmount();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function updateBeneficiary(address newBeneficiary) external onlyOwner {
|
|
86
|
+
require(newBeneficiary != address(0), "Zero address");
|
|
87
|
+
require(!revoked, "Vesting revoked");
|
|
88
|
+
emit BeneficiaryUpdated(beneficiary, newBeneficiary);
|
|
89
|
+
beneficiary = newBeneficiary;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function transferOwnership(address newOwner) external onlyOwner {
|
|
93
|
+
require(newOwner != address(0), "New owner is zero address");
|
|
94
|
+
owner = newOwner;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function vestingSchedule() external view returns (
|
|
98
|
+
uint256 _start,
|
|
99
|
+
uint256 _cliff,
|
|
100
|
+
uint256 _duration,
|
|
101
|
+
uint256 _total,
|
|
102
|
+
uint256 _released,
|
|
103
|
+
uint256 _releasable,
|
|
104
|
+
bool _revoked
|
|
105
|
+
) {
|
|
106
|
+
return (
|
|
107
|
+
start,
|
|
108
|
+
start + cliffDuration,
|
|
109
|
+
vestingDuration,
|
|
110
|
+
totalAmount,
|
|
111
|
+
released,
|
|
112
|
+
_releasableAmount(),
|
|
113
|
+
revoked
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function _releasableAmount() internal view returns (uint256) {
|
|
118
|
+
return _vestedAmount() - released;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function _vestedAmount() internal view returns (uint256) {
|
|
122
|
+
if (block.timestamp < start + cliffDuration) {
|
|
123
|
+
return 0;
|
|
124
|
+
}
|
|
125
|
+
uint256 elapsed = block.timestamp - start;
|
|
126
|
+
if (elapsed >= vestingDuration) {
|
|
127
|
+
return totalAmount;
|
|
128
|
+
}
|
|
129
|
+
return (totalAmount * elapsed) / vestingDuration;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
`;
|
|
133
|
+
//# sourceMappingURL=vesting.sol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vesting.sol.js","sourceRoot":"","sources":["../../../src/generator/templates/vesting.sol.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmI/B,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function extractContractName(source: string): string;
|
|
2
|
+
export declare function sanitizeFileName(name: string): string;
|
|
3
|
+
export declare function writeFileUnique(dir: string, fileName: string, content: string): Promise<string>;
|
|
4
|
+
export declare function ensureOutputDir(dir: string): Promise<void>;
|
|
5
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/generator/utils.ts"],"names":[],"mappings":"AAIA,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAWrD;AAED,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CAqBjB;AAED,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGhE"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { writeFile } from "node:fs/promises";
|
|
2
|
+
import { mkdir } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
export function extractContractName(source) {
|
|
5
|
+
const match = source.match(/contract\s+([A-Za-z_][A-Za-z0-9_]*)\s*(?:is\s|{)/);
|
|
6
|
+
if (match) {
|
|
7
|
+
return match[1];
|
|
8
|
+
}
|
|
9
|
+
return "GeneratedContract";
|
|
10
|
+
}
|
|
11
|
+
export function sanitizeFileName(name) {
|
|
12
|
+
const cleaned = name.replace(/[^a-zA-Z0-9]/g, " ");
|
|
13
|
+
const pascal = cleaned
|
|
14
|
+
.split(/\s+/)
|
|
15
|
+
.filter(Boolean)
|
|
16
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
17
|
+
.join("");
|
|
18
|
+
if (!pascal) {
|
|
19
|
+
return "Contract.sol";
|
|
20
|
+
}
|
|
21
|
+
return pascal.endsWith(".sol") ? pascal : `${pascal}.sol`;
|
|
22
|
+
}
|
|
23
|
+
export async function writeFileUnique(dir, fileName, content) {
|
|
24
|
+
const ext = path.extname(fileName);
|
|
25
|
+
const base = fileName.slice(0, -ext.length);
|
|
26
|
+
let candidate = path.resolve(dir, fileName);
|
|
27
|
+
let counter = 0;
|
|
28
|
+
const maxAttempts = 100;
|
|
29
|
+
while (counter < maxAttempts) {
|
|
30
|
+
try {
|
|
31
|
+
await writeFile(candidate, content, { encoding: "utf-8", flag: "wx" });
|
|
32
|
+
return candidate;
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
if (err.code === "EEXIST") {
|
|
36
|
+
counter++;
|
|
37
|
+
candidate = path.resolve(dir, `${base}_${counter}${ext}`);
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
throw err;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
throw new Error(`Could not find unique filename for ${fileName} after ${maxAttempts} attempts`);
|
|
44
|
+
}
|
|
45
|
+
export async function ensureOutputDir(dir) {
|
|
46
|
+
const resolved = path.resolve(dir);
|
|
47
|
+
await mkdir(resolved, { recursive: true });
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/generator/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;IAC/E,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,mBAAmB,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,OAAO;SACnB,KAAK,CAAC,KAAK,CAAC;SACZ,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;SACzE,IAAI,CAAC,EAAE,CAAC,CAAC;IACZ,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,cAAc,CAAC;IACxB,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,MAAM,CAAC;AAC5D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAW,EACX,QAAgB,EAChB,OAAe;IAEf,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5C,IAAI,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC5C,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,MAAM,WAAW,GAAG,GAAG,CAAC;IAExB,OAAO,OAAO,GAAG,WAAW,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,SAAS,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACvE,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrD,OAAO,EAAE,CAAC;gBACV,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,OAAO,GAAG,GAAG,EAAE,CAAC,CAAC;gBAC1D,SAAS;YACX,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,sCAAsC,QAAQ,UAAU,WAAW,WAAW,CAAC,CAAC;AAClG,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,GAAW;IAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACnC,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC7C,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
|