Skip to content

Commit e90b7e7

Browse files
committed
another big refactor add worker contract and payment
1 parent de6dbca commit e90b7e7

File tree

11 files changed

+689
-297
lines changed

11 files changed

+689
-297
lines changed

script/UpgradeV7.s.sol

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.26;
3+
4+
import {Script, console} from "forge-std/Script.sol";
5+
import {Upgrades, Options} from "openzeppelin-foundry-upgrades/Upgrades.sol";
6+
import {BlueprintV6} from "../src/BlueprintV6.sol";
7+
8+
contract DeployScript is Script {
9+
function setUp() public {}
10+
11+
function run() public {
12+
vm.startBroadcast();
13+
14+
address proxyAddr = vm.envAddress("PROXY_ADDRESS");
15+
Options memory opts;
16+
opts.referenceContract = "BlueprintV5.sol";
17+
Upgrades.upgradeProxy(
18+
proxyAddr, "BlueprintV6.sol:BlueprintV6", abi.encodeCall(BlueprintV6.initialize, ()), opts
19+
);
20+
BlueprintV6 proxy = BlueprintV6(proxyAddr);
21+
console.log("New Version:", proxy.VERSION());
22+
23+
vm.stopBroadcast();
24+
}
25+
}

src/Agent.sol

Lines changed: 98 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ import "@openzeppelin/contracts/metatx/ERC2771Context.sol";
66
import "./Payment.sol";
77
import "./Blueprint.sol";
88

9-
contract Agent is ERC2771Context {
10-
address public blueprintCore;
9+
contract Agent is ERC2771Context, Payment {
10+
address public blueprintStorageProxy;
11+
address public trustRouter;
12+
string public VERSION;
1113

1214
event SetCopyAgentFee(bytes32 indexed agentRequestID, address userAddress, address tokenAddress, uint256 fee);
1315
event CopyAgentRequest(bytes32 indexed copyID, bytes32 indexed originalAgentRequestID, address userAddress);
@@ -24,36 +26,41 @@ contract Agent is ERC2771Context {
2426
uint256 amount
2527
);
2628

27-
constructor(address _core, address trustedForwarder) ERC2771Context(trustedForwarder) {
28-
blueprintCore = _core;
29+
constructor(address _blueprintStorageProxy, address _trustedForwarder, string memory _version)
30+
ERC2771Context(_trustedForwarder)
31+
{
32+
trustRouter = _trustedForwarder;
33+
blueprintStorageProxy = _blueprintStorageProxy;
34+
VERSION = _version;
2935
}
3036

3137
function setCopyAgentFee(bytes32 agentRequestID, address tokenAddress, uint256 fee) external {
3238
require(fee > 0, "Fee must be greater than 0");
33-
require(Blueprint(blueprintCore).paymentAddressEnableMp(tokenAddress), "Invalid token address");
39+
require(Blueprint(blueprintStorageProxy).paymentAddressEnableMp(tokenAddress), "Invalid token address");
3440
address sender = _msgSender();
35-
require(Blueprint(blueprintCore).getDeploymentOwner(agentRequestID) == sender, "Not owner");
41+
require(Blueprint(blueprintStorageProxy).getDeploymentOwner(agentRequestID) == sender, "Not owner");
3642

37-
Blueprint(blueprintCore).setCopyAgentFeeStorage(agentRequestID, tokenAddress, fee);
43+
Blueprint(blueprintStorageProxy).setCopyAgentFeeStorage(agentRequestID, tokenAddress, fee);
3844
emit SetCopyAgentFee(agentRequestID, sender, tokenAddress, fee);
3945
}
4046

4147
function setCopyAgentFeeWithSig(bytes32 agentRequestID, address tokenAddress, uint256 fee, bytes memory signature)
4248
external
4349
{
44-
address owner = Blueprint(blueprintCore).getDeploymentOwner(agentRequestID);
50+
address owner = Blueprint(blueprintStorageProxy).getDeploymentOwner(agentRequestID);
4551
require(owner != address(0), "Invalid agentRequestID");
4652
require(fee > 0, "Fee must be greater than 0");
47-
require(Blueprint(blueprintCore).paymentAddressEnableMp(tokenAddress), "Invalid token address");
53+
require(Blueprint(blueprintStorageProxy).paymentAddressEnableMp(tokenAddress), "Invalid token address");
4854

49-
uint256 nonce = Blueprint(blueprintCore).getUserNonce(owner);
50-
bytes32 digest = Blueprint(blueprintCore).getSetCopyAgentFeeDigest(agentRequestID, tokenAddress, fee, nonce);
51-
address signer = Blueprint(blueprintCore).getSignerAddress(digest, signature);
55+
uint256 nonce = Blueprint(blueprintStorageProxy).getUserNonce(owner);
56+
bytes32 digest =
57+
Blueprint(blueprintStorageProxy).getSetCopyAgentFeeDigest(agentRequestID, tokenAddress, fee, nonce);
58+
address signer = Blueprint(blueprintStorageProxy).getSignerAddress(digest, signature);
5259

5360
require(signer == owner, "Wrong owner signature");
5461

55-
Blueprint(blueprintCore).setCopyAgentFeeStorage(agentRequestID, tokenAddress, fee);
56-
Blueprint(blueprintCore).incrementUserNonce(owner);
62+
Blueprint(blueprintStorageProxy).setCopyAgentFeeStorage(agentRequestID, tokenAddress, fee);
63+
Blueprint(blueprintStorageProxy).incrementUserNonce(owner);
5764

5865
emit SetCopyAgentFee(agentRequestID, owner, tokenAddress, fee);
5966
}
@@ -71,13 +78,14 @@ contract Agent is ERC2771Context {
7178
address tokenAddress,
7279
bytes memory signature
7380
) public payable {
74-
require(Blueprint(blueprintCore).paymentAddressEnableMp(tokenAddress), "Invalid token address");
81+
require(Blueprint(blueprintStorageProxy).paymentAddressEnableMp(tokenAddress), "Invalid token address");
7582

7683
// get digest
77-
bytes32 digest =
78-
Blueprint(blueprintCore).getCreateCopyAgentRequestDigest(copyID, originalAgentRequestID, tokenAddress);
84+
bytes32 digest = Blueprint(blueprintStorageProxy).getCreateCopyAgentRequestDigest(
85+
copyID, originalAgentRequestID, tokenAddress
86+
);
7987
// get signer address
80-
address signer = Blueprint(blueprintCore).getSignerAddress(digest, signature);
88+
address signer = Blueprint(blueprintStorageProxy).getSignerAddress(digest, signature);
8189

8290
// get signer address, notice signer cannot be owner of the original agent request
8391

@@ -90,30 +98,34 @@ contract Agent is ERC2771Context {
9098
address tokenAddress,
9199
address userAddress
92100
) internal {
93-
require(Blueprint(blueprintCore).paymentAddressEnableMp(tokenAddress), "Invalid token address");
101+
require(Blueprint(blueprintStorageProxy).paymentAddressEnableMp(tokenAddress), "Invalid token address");
94102

95-
address owner = Blueprint(blueprintCore).getDeploymentOwner(originalAgentRequestID);
103+
address owner = Blueprint(blueprintStorageProxy).getDeploymentOwner(originalAgentRequestID);
96104
require(owner != address(0), "Invalid original agent request ID");
97105

98-
uint256 fee = Blueprint(blueprintCore).copyAgentFeeMp(originalAgentRequestID, tokenAddress);
106+
uint256 fee = Blueprint(blueprintStorageProxy).copyAgentFeeMp(originalAgentRequestID, tokenAddress);
99107
require(fee > 0, "Copy Agent is not set by the owner");
100108

101109
// check platformFee is set or not
102-
require(Blueprint(blueprintCore).platformCopyAgentFee() > 0, "Platform fee is not set");
110+
require(Blueprint(blueprintStorageProxy).platformCopyAgentFee() > 0, "Platform fee is not set");
103111

104112
// calculate platform and creator fees
105113
uint256 platformFee =
106-
(fee * Blueprint(blueprintCore).platformCopyAgentFee()) / Blueprint(blueprintCore).factor();
114+
(fee * Blueprint(blueprintStorageProxy).platformCopyAgentFee()) / Blueprint(blueprintStorageProxy).factor();
107115

108116
uint256 creatorFee = fee - platformFee;
109117

110-
address feeWallet = Blueprint(blueprintCore).feeCollectionWalletAddress();
111-
118+
address feeWallet = Blueprint(blueprintStorageProxy).feeCollectionWalletAddress();
119+
address fromAddr = getPaymentFromAddress();
120+
if (fromAddr != address(this)) {
121+
// if the payment is not from the agent contract, we use the user address
122+
fromAddr = userAddress;
123+
}
112124
// pay the platform fee to the fee collection wallet
113-
Blueprint(blueprintCore).forwardPayWithERC20(tokenAddress, platformFee, userAddress, feeWallet);
125+
payWithERC20(tokenAddress, platformFee, fromAddr, feeWallet);
114126

115127
// pay the creator fee to the owner of the original agent request
116-
Blueprint(blueprintCore).forwardPayWithERC20(tokenAddress, creatorFee, userAddress, owner);
128+
payWithERC20(tokenAddress, creatorFee, fromAddr, owner);
117129

118130
emit CopyAgentRequest(copyID, originalAgentRequestID, userAddress);
119131
}
@@ -125,7 +137,8 @@ contract Agent is ERC2771Context {
125137
string memory serverURL,
126138
address tokenAddress
127139
) public payable returns (bytes32 requestID) {
128-
requestID = Blueprint(blueprintCore).createAgent(
140+
//todo: migrate payment logic
141+
requestID = Blueprint(blueprintStorageProxy).createAgent(
129142
_msgSender(), projectId, base64Proposal, privateWorkerAddress, serverURL, 0, tokenAddress
130143
);
131144
}
@@ -139,14 +152,15 @@ contract Agent is ERC2771Context {
139152
bytes memory signature
140153
) public payable returns (bytes32 requestID) {
141154
// get EIP712 hash digest
142-
bytes32 digest = Blueprint(blueprintCore).getCreateAgentWithTokenDigest(
155+
bytes32 digest = Blueprint(blueprintStorageProxy).getCreateAgentWithTokenDigest(
143156
projectId, base64Proposal, serverURL, privateWorkerAddress, tokenAddress
144157
);
145158

146159
// get signer address
147-
address signerAddr = Blueprint(blueprintCore).getSignerAddress(digest, signature);
160+
address signerAddr = Blueprint(blueprintStorageProxy).getSignerAddress(digest, signature);
148161

149-
requestID = Blueprint(blueprintCore).createAgent(
162+
//todo: migrate payment logic
163+
requestID = Blueprint(blueprintStorageProxy).createAgent(
150164
signerAddr, projectId, base64Proposal, privateWorkerAddress, serverURL, 0, tokenAddress
151165
);
152166
}
@@ -157,7 +171,8 @@ contract Agent is ERC2771Context {
157171
bytes32 requestID,
158172
string memory updatedBase64Config
159173
) public payable {
160-
Blueprint(blueprintCore).updateWorkerDeploymentConfigCommon(
174+
//todo: migrate payment logic
175+
Blueprint(blueprintStorageProxy).updateWorkerDeploymentConfigCommon(
161176
tokenAddress, _msgSender(), projectId, requestID, updatedBase64Config
162177
);
163178
}
@@ -169,36 +184,74 @@ contract Agent is ERC2771Context {
169184
string memory updatedBase64Config,
170185
bytes memory signature
171186
) public payable {
172-
address owner = Blueprint(blueprintCore).getDeploymentOwner(requestID);
187+
address owner = Blueprint(blueprintStorageProxy).getDeploymentOwner(requestID);
173188
require(owner != address(0), "Invalid requestID");
174189

175190
// get EIP712 hash digest
176-
bytes32 digest = Blueprint(blueprintCore).getUpdateWorkerConfigDigest(
177-
tokenAddress, projectId, requestID, updatedBase64Config, Blueprint(blueprintCore).getUserNonce(owner)
191+
bytes32 digest = Blueprint(blueprintStorageProxy).getUpdateWorkerConfigDigest(
192+
tokenAddress,
193+
projectId,
194+
requestID,
195+
updatedBase64Config,
196+
Blueprint(blueprintStorageProxy).getUserNonce(owner)
178197
);
179198

180199
// get signer address
181-
address signerAddr = Blueprint(blueprintCore).getSignerAddress(digest, signature);
200+
address signerAddr = Blueprint(blueprintStorageProxy).getSignerAddress(digest, signature);
182201

183202
// check if signer address is owner of requestID
184203
require(signerAddr == owner, "Invalid signature");
185-
186-
Blueprint(blueprintCore).updateWorkerDeploymentConfigCommon(
204+
//todo: migrate payment logic
205+
Blueprint(blueprintStorageProxy).updateWorkerDeploymentConfigCommon(
187206
tokenAddress, signerAddr, projectId, requestID, updatedBase64Config
188207
);
189208

190-
Blueprint(blueprintCore).incrementUserNonce(owner);
209+
Blueprint(blueprintStorageProxy).incrementUserNonce(owner);
210+
}
211+
212+
function topUp(address toUserAddress, address tokenAddress, uint256 amount) internal {
213+
require(amount > 0, "Amount must be greater than 0");
214+
215+
require(Blueprint(blueprintStorageProxy).paymentAddressEnableMp(tokenAddress), "Payment address is not valid");
216+
217+
// update user top up
218+
Blueprint(blueprintStorageProxy).AddUserTopUpAmount(toUserAddress, tokenAddress, amount);
219+
220+
address feeCollectionWalletAddress = Blueprint(blueprintStorageProxy).feeCollectionWalletAddress();
221+
222+
if (tokenAddress == address(0)) {
223+
require(msg.value == amount, "Native token amount mismatch");
224+
225+
// payment to fee collection wallet address with ether
226+
payWithNativeToken(payable(feeCollectionWalletAddress), amount);
227+
} else {
228+
// payment to feeCollectionWalletAddress with token, fromAddress always from msg.sender, either router or real user
229+
payWithERC20(tokenAddress, amount, getPaymentFromAddress(), feeCollectionWalletAddress);
230+
}
231+
}
232+
233+
function getPaymentFromAddress() internal view returns (address) {
234+
// payment goes to router and router transfer fund into agent contract and then agent contract process from here
235+
// if the sender is the trust router, we use the agent contract address as the from address
236+
// otherwise, we use the real user address
237+
return (msg.sender == trustRouter) ? address(this) : _msgSender();
191238
}
192239

193240
function userTopUp(address tokenAddress, uint256 amount) public payable {
194-
Blueprint(blueprintCore).topUp(msg.sender, tokenAddress, amount);
195-
address feeCollectionWalletAddress = Blueprint(blueprintCore).feeCollectionWalletAddress();
196-
emit UserTopUp(msg.sender, feeCollectionWalletAddress, tokenAddress, amount);
241+
topUp(_msgSender(), tokenAddress, amount);
242+
emit UserTopUp(
243+
_msgSender(), Blueprint(blueprintStorageProxy).feeCollectionWalletAddress(), tokenAddress, amount
244+
);
197245
}
198246

199247
function userTopUpOther(address userAddress, address tokenAddress, uint256 amount) public payable {
200-
Blueprint(blueprintCore).topUp(userAddress, tokenAddress, amount);
201-
address feeCollectionWalletAddress = Blueprint(blueprintCore).feeCollectionWalletAddress();
202-
emit UserTopUpOther(msg.sender, userAddress, feeCollectionWalletAddress, tokenAddress, amount);
248+
topUp(userAddress, tokenAddress, amount);
249+
emit UserTopUpOther(
250+
_msgSender(),
251+
userAddress,
252+
Blueprint(blueprintStorageProxy).feeCollectionWalletAddress(),
253+
tokenAddress,
254+
amount
255+
);
203256
}
204257
}

src/Blueprint.sol

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ contract Blueprint is Initializable, OwnableUpgradeable, BlueprintCore {
1515
event UpdateWorker(address workerAddress, bool isTrusted);
1616
event CreditReward(address indexed userAddress, uint256 amount);
1717
event SetGlobalPlatformFee(uint256 fee, uint256 factor);
18+
event SetAdminContract(address agentContract);
1819

1920
modifier isAdmin() {
2021
// slither-disable-next-line timestamp
@@ -129,8 +130,10 @@ contract Blueprint is Initializable, OwnableUpgradeable, BlueprintCore {
129130
emit CreditReward(userAddress, amount);
130131
}
131132

132-
function setAgentContract(address _agent) public onlyOwner {
133-
agentContract = _agent;
133+
function setAdminContract(address _adminContract) public onlyOwner {
134+
require(_adminContract != address(0), "Admin contract address is invalid");
135+
adminContracts[_adminContract] = true;
136+
emit SetAdminContract(_adminContract);
134137
}
135138

136139
// 6 %。= 6 / 100 means fee =6 and baseFactor = 100

0 commit comments

Comments
 (0)