-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathFunctions.s.sol
165 lines (140 loc) · 6.66 KB
/
Functions.s.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.9.0;
import "forge-std/Script.sol";
import "../helpers/BaseScript.s.sol";
import "src/interfaces/functions/IFunctionsRouter.sol";
import "src/interfaces/functions/IFunctionsBilling.sol";
import "src/interfaces/functions/IFunctionsSubscriptions.sol";
import "src/interfaces/shared/LinkTokenInterface.sol";
import "src/interfaces/shared/AccessControllerInterface.sol";
import "src/libraries/Utils.sol";
contract FunctionsScript is BaseScript {
address public functionsRouterAddress;
/// @notice MODIFIERS
modifier isAllowListed() {
IFunctionsRouter functionsRouter = IFunctionsRouter(functionsRouterAddress);
bytes32 allowListId = functionsRouter.getAllowListId();
if (allowListId == bytes32(0)) {
_;
return;
}
address allowListAddress = functionsRouter.getContractById(allowListId); // Ensure the allow list exists
if (allowListAddress != address(0)) {
AccessControllerInterface allowList = AccessControllerInterface(allowListAddress);
bytes memory checkData = new bytes(0);
require(allowList.hasAccess(msg.sender, checkData), "Sender not authorized by Functions Router allow list");
}
_;
}
constructor (address _functionsRouterAddress) {
functionsRouterAddress = _functionsRouterAddress;
}
/// @notice Functions Router functions
function createSubscription() nestedScriptContext isAllowListed external returns(uint64 subscriptionId) {
IFunctionsSubscriptions functionsRouter = IFunctionsSubscriptions(functionsRouterAddress);
subscriptionId = functionsRouter.createSubscription();
console.log("Created subscription with ID:", subscriptionId);
return subscriptionId;
}
function createSubscriptionWithConsumer(
address consumerAddress
) nestedScriptContext isAllowListed external returns(uint64 subscriptionId) {
IFunctionsSubscriptions functionsRouter = IFunctionsSubscriptions(functionsRouterAddress);
subscriptionId = functionsRouter.createSubscriptionWithConsumer(consumerAddress);
console.log("Created subscription with consumer with ID:", subscriptionId);
return subscriptionId;
}
function fundSubscription(
address linkTokenAddress,
uint256 amountInJuels,
uint64 subscriptionId
) nestedScriptContext isAllowListed external {
IFunctionsSubscriptions functionsRouter = IFunctionsSubscriptions(functionsRouterAddress);
LinkTokenInterface linkToken = LinkTokenInterface(linkTokenAddress);
require(amountInJuels > 0, "Juels funding amount must be greater than 0");
// Ensure the subscription exists
IFunctionsSubscriptions.Subscription memory subscription = functionsRouter.getSubscription(subscriptionId);
require (subscription.owner != address(0), "Subscription not found");
address signer = msg.sender; // The address executing the script
require(linkToken.balanceOf(signer) >= amountInJuels, "Insufficient LINK balance");
// Perform the transfer and call
linkToken.transferAndCall(functionsRouterAddress, amountInJuels, abi.encode(subscriptionId));
console.log("Funded subscription with ID:", subscriptionId);
}
function cancelSubscription(
uint64 subscriptionId,
address receivingAddress
) nestedScriptContext isAllowListed external {
IFunctionsSubscriptions functionsRouter = IFunctionsSubscriptions(functionsRouterAddress);
functionsRouter.cancelSubscription(subscriptionId, receivingAddress);
console.log("Cancelled subscription with ID:", subscriptionId);
}
function getSubscriptionDetails(
uint64 subscriptionId
) external view returns(IFunctionsSubscriptions.Subscription memory subscriptionDetails) {
IFunctionsSubscriptions functionsRouter = IFunctionsSubscriptions(functionsRouterAddress);
return functionsRouter.getSubscription(subscriptionId);
}
function addConsumer(
uint64 subscriptionId,
address consumer
) nestedScriptContext isAllowListed external {
IFunctionsSubscriptions functionsRouter = IFunctionsSubscriptions(functionsRouterAddress);
functionsRouter.addConsumer(subscriptionId, consumer);
console.log("Added consumer to subscription ID:", subscriptionId);
}
function removeConsumer(
uint64 subscriptionId,
address consumer
) nestedScriptContext isAllowListed external {
IFunctionsSubscriptions functionsRouter = IFunctionsSubscriptions(functionsRouterAddress);
functionsRouter.removeConsumer(subscriptionId, consumer);
console.log("Removed consumer from subscription ID:", subscriptionId);
}
function proposeSubscriptionOwnerTransfer(
uint64 subscriptionId,
address newOwner
) nestedScriptContext isAllowListed external {
IFunctionsSubscriptions functionsRouter = IFunctionsSubscriptions(functionsRouterAddress);
functionsRouter.proposeSubscriptionOwnerTransfer(subscriptionId, newOwner);
console.log("Proposed subscription owner transfer for ID:", subscriptionId);
}
function acceptSubscriptionOwnerTransfer(
uint64 subscriptionId
) nestedScriptContext isAllowListed external {
IFunctionsSubscriptions functionsRouter = IFunctionsSubscriptions(functionsRouterAddress);
functionsRouter.acceptSubscriptionOwnerTransfer(subscriptionId);
console.log("Accepted subscription owner transfer for ID:", subscriptionId);
}
function timeoutRequests(
FunctionsResponse.Commitment[] memory commitments
) nestedScriptContext isAllowListed external {
require(commitments.length > 0, "Must provide at least one request commitment");
IFunctionsSubscriptions functionsRouter = IFunctionsSubscriptions(functionsRouterAddress);
functionsRouter.timeoutRequests(commitments);
console.log("Timed out requests");
}
function estimateRequestCost(
string memory donId,
uint64 subscriptionId,
uint32 callbackGasLimit,
uint256 gasPriceWei
) nestedScriptContext isAllowListed external returns(uint96 estimatedCost) {
require(gasPriceWei > 0, "Gas price must be greater than 0");
require(callbackGasLimit > 0, "Callback gas limit must be greater than 0");
IFunctionsRouter functionsRouter = IFunctionsRouter(functionsRouterAddress);
bytes32 donIdBytes32 = Utils.stringToBytes32(donId);
address functionsCoordinatorAddress = functionsRouter.getContractById(donIdBytes32);
require(functionsCoordinatorAddress != address(0), "Functions Coordinator not found");
IFunctionsBilling functionsCoordinator = IFunctionsBilling(functionsCoordinatorAddress);
bytes memory requestData = new bytes(0);
estimatedCost = functionsCoordinator.estimateCost(
subscriptionId,
requestData,
callbackGasLimit,
gasPriceWei
);
console.log("Estimated request cost:", estimatedCost);
return estimatedCost;
}
}