Skip to content

Commit 190b1c9

Browse files
committed
Following modifications
1 parent 642583c commit 190b1c9

8 files changed

Lines changed: 105 additions & 62 deletions

File tree

packages/foundry/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,5 @@ lint:
6363
verify:
6464
forge script script/VerifyAll.s.sol --ffi --rpc-url $(RPC_URL)
6565

66+
verify-sourcify:
67+
forge verify-contract 0xb6fc60Ab923043D90907724c58B2BAf009586247 Delivery --chain 10143 --verifier sourcify --verifier-url https://sourcify-api-monad.blockvision.org

packages/foundry/contracts/Contractly.sol

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,12 @@ contract Contractly {
4545
struct Party {
4646
bool requiresSignature;
4747
bool requiresStaking;
48-
uint256 stakeRatio; // Percentage of total stake amount (1-100)
48+
uint8 stakeRatio; // Percentage of total stake amount (1-100)
4949
bool hasSigned; // Whether the party has signed the agreement
5050
}
5151

5252
struct Agreement {
5353
uint256 id;
54-
string title;
5554
address creator;
5655
mapping(address => Party) parties;
5756
uint256 creationTime;
@@ -60,6 +59,7 @@ contract Contractly {
6059
uint256 totalStakingAmount;
6160
AgreementStatus status;
6261
address[] partyAddresses;
62+
mapping(address => bool) isParty;
6363
}
6464

6565
// Mapping from agreement ID to Agreement
@@ -69,7 +69,7 @@ contract Contractly {
6969
mapping(uint256 => mapping(address => uint256)) public stakedFunds;
7070

7171
// ======== Events ========
72-
event AgreementCreated(uint256 agreementId, address creator, string title);
72+
event AgreementCreated(uint256 agreementId, address creator);
7373
event AgreementSigned(uint256 agreementId, address party);
7474
event AgreementLocked(uint256 agreementId);
7575
event AgreementActivated(uint256 agreementId);
@@ -96,15 +96,7 @@ contract Contractly {
9696
}
9797

9898
modifier onlyParty(uint256 _agreementId) {
99-
bool isParty = false;
100-
Agreement storage agreement = agreements[_agreementId];
101-
for (uint256 i = 0; i < agreement.partyAddresses.length; i++) {
102-
if (agreement.partyAddresses[i] == msg.sender) {
103-
isParty = true;
104-
break;
105-
}
106-
}
107-
if (!isParty) revert NotAgreementParty();
99+
if (!agreements[_agreementId].isParty[msg.sender]) revert NotAgreementParty();
108100
_;
109101
}
110102

@@ -122,19 +114,17 @@ contract Contractly {
122114

123115
/**
124116
* @dev Creates a new agreement - can only be called by authorized contracts
125-
* @param _title Title of the agreement
126117
* @param _creator Creator of the agreement
127118
* @param _expirationTime Timestamp when the agreement expires
128119
* @param _totalStakingAmount Total amount that needs to be staked across all parties
129120
*/
130-
function createAgreement(string memory _title, address _creator, uint256 _expirationTime, uint256 _totalStakingAmount) external onlyAuthorizedContract returns (uint256) {
121+
function createAgreement(address _creator, uint256 _expirationTime, uint256 _totalStakingAmount) external onlyAuthorizedContract returns (uint256) {
131122
if (_expirationTime <= block.timestamp) revert FutureExpirationRequired();
132123

133124
uint256 agreementId = agreementCount;
134125
Agreement storage newAgreement = agreements[agreementId];
135126

136127
newAgreement.id = agreementId;
137-
newAgreement.title = _title;
138128
newAgreement.creator = _creator;
139129
newAgreement.creationTime = block.timestamp;
140130
newAgreement.expirationTime = _expirationTime;
@@ -143,7 +133,7 @@ contract Contractly {
143133

144134
agreementCount++;
145135

146-
emit AgreementCreated(agreementId, msg.sender, _title);
136+
emit AgreementCreated(agreementId, msg.sender);
147137

148138
return agreementId;
149139
}
@@ -155,7 +145,7 @@ contract Contractly {
155145
* @param _requiresStaking Whether this party needs to stake funds
156146
* @param _stakeRatio Percentage of total stake this party needs to provide (1-100)
157147
*/
158-
function addParty(uint256 _agreementId, address _partyAddress, bool _requiresSignature, bool _requiresStaking, uint256 _stakeRatio) external agreementExists(_agreementId) onlyPendingStatus(_agreementId) onlyAuthorizedContract {
148+
function addParty(uint256 _agreementId, address _partyAddress, bool _requiresSignature, bool _requiresStaking, uint8 _stakeRatio) external agreementExists(_agreementId) onlyPendingStatus(_agreementId) onlyAuthorizedContract {
159149
Agreement storage agreement = agreements[_agreementId];
160150

161151
_requiresStaking = _requiresSignature ? _requiresStaking : false;
@@ -219,15 +209,19 @@ contract Contractly {
219209
agreement.status = AgreementStatus.Fulfilled;
220210

221211
// Return staked funds to all parties
222-
for (uint256 i = 0; i < agreement.partyAddresses.length; i++) {
223-
address party = agreement.partyAddresses[i];
224-
uint256 amount = getStakedAmount(_agreementId, party);
212+
address[] memory parties = agreement.partyAddresses;
213+
uint256 partyCount = parties.length;
214+
215+
for (uint256 i = 0; i < partyCount;) {
216+
address party = parties[i];
217+
uint256 amount = stakedFunds[_agreementId][party];
225218
if (amount > 0) {
226219
stakedFunds[_agreementId][party] = 0;
227220
(bool success,) = party.call{ value: amount }("");
228221
if (!success) revert FundsTransferFailed();
229222
emit FundsReleased(_agreementId, party, amount);
230223
}
224+
unchecked { ++i; }
231225
}
232226
emit AgreementFulfilled(_agreementId);
233227
}
@@ -377,7 +371,7 @@ contract Contractly {
377371
return (agreement.totalStakingAmount * party.stakeRatio) / 100;
378372
}
379373

380-
function _addToAgreementParties(Agreement storage _agreement, address _partyAddress, bool _requiresSignature, bool _requiresStaking, uint256 _stakeRatio) internal {
374+
function _addToAgreementParties(Agreement storage _agreement, address _partyAddress, bool _requiresSignature, bool _requiresStaking, uint8 _stakeRatio) internal {
381375
_agreement.parties[_partyAddress] = Party({ requiresSignature: _requiresSignature, requiresStaking: _requiresStaking, stakeRatio: _stakeRatio, hasSigned: false });
382376
_agreement.partyAddresses.push(_partyAddress);
383377
}
@@ -392,9 +386,9 @@ contract Contractly {
392386
return stakedFunds[_agreementId][_party];
393387
}
394388

395-
function getAgreement(uint256 _agreementId) public view agreementExists(_agreementId) returns (uint256 id, string memory title, address creator, uint256 creationTime, uint256 expirationTime, uint256 disputeWindowDuration, uint256 totalStakingAmount, AgreementStatus status, address[] memory partyAddresses) {
389+
function getAgreement(uint256 _agreementId) public view agreementExists(_agreementId) returns (uint256 id, address creator, uint256 creationTime, uint256 expirationTime, uint256 disputeWindowDuration, uint256 totalStakingAmount, AgreementStatus status, address[] memory partyAddresses) {
396390
Agreement storage agreement = agreements[_agreementId];
397-
return (agreement.id, agreement.title, agreement.creator, agreement.creationTime, agreement.expirationTime, agreement.disputeWindowDuration, agreement.totalStakingAmount, agreement.status, agreement.partyAddresses);
391+
return (agreement.id, agreement.creator, agreement.creationTime, agreement.expirationTime, agreement.disputeWindowDuration, agreement.totalStakingAmount, agreement.status, agreement.partyAddresses);
398392
}
399393

400394
function getParty(uint256 _agreementId, address _partyAddress) public view agreementExists(_agreementId) returns (bool requiresStaking, uint256 stakeRatio, bool hasSigned) {

packages/foundry/contracts/Delivery.sol

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,57 +11,57 @@ contract Delivery {
1111

1212
// ======== State Variables ========
1313
Contractly public contractly;
14+
uint256 private lastAutomationUpdate;
1415
mapping(uint256 agreementId => bool hasVendorAssigned) private hasVendorAssigned;
1516

1617
// ======== Events ========
17-
event AgreementCreated(uint256 indexed agreementId, string title, address creator);
18-
event DeliveryCreated(uint256 indexed agreementId, string title, address vendor, address customer);
19-
event BatchDeliveryCreated(string[] titles, uint256[] expirationTimes, uint256[] totalStakingAmounts, address[] customerAddresses);
18+
event AgreementCreated(uint256 indexed agreementId, address creator);
19+
event DeliveryCreated(uint256 indexed agreementId, address vendor, address customer);
20+
event BatchDeliveryCreated(uint256[] expirationTimes, uint256[] totalStakingAmounts, address[] customerAddresses);
2021

2122
// ======== Constructor ========
2223
constructor(address _contractlyAddress) {
2324
contractly = Contractly(_contractlyAddress);
25+
lastAutomationUpdate = 0;
2426
}
2527

2628
// ======== Core Functions ========
2729

2830
/**
2931
* @dev Creates a new delivery (vendor -> customer) agreement
30-
* @param _title The title of the agreement
3132
* @param _expirationTime The timestamp when the agreement expires
3233
* @param _totalStakingAmount The total amount that needs to be staked across all parties
3334
* @param _customerAddress The address of the customer
3435
*/
35-
function createDelivery(string memory _title, uint256 _expirationTime, uint256 _totalStakingAmount, address _customerAddress) public payable returns (uint256) {
36-
uint256 agreementId = _createAgreement(_title, _expirationTime, _totalStakingAmount);
36+
function createDelivery(uint256 _expirationTime, uint256 _totalStakingAmount, address _customerAddress) public payable returns (uint256) {
37+
uint256 agreementId = _createAgreement(_expirationTime, _totalStakingAmount);
3738
_addVendorParty(agreementId, msg.sender);
3839
_addCustomerParty(agreementId, _customerAddress);
3940
_signAgreement(agreementId);
4041
stakeAgreement(agreementId, _totalStakingAmount);
4142
contractly.lockAgreement(agreementId);
42-
emit DeliveryCreated(agreementId, _title, msg.sender, _customerAddress);
43+
emit DeliveryCreated(agreementId, msg.sender, _customerAddress);
4344
return agreementId;
4445
}
4546

4647
/**
4748
* @dev Creates multiple delivery (vendor -> customer)[] agreements.
48-
* @param _titles The titles of the agreements
4949
* @param _expirationTimes The timestamps when the agreements expire
5050
* @param _totalStakingAmounts The total amounts that need to be staked across all parties
5151
* @param _customerAddresses The addresses of the customers
5252
*/
53-
function batchCreateDelivery(string[] memory _titles, uint256[] memory _expirationTimes, uint256[] memory _totalStakingAmounts, address[] memory _customerAddresses) public payable returns (uint256[] memory) {
53+
function batchCreateDelivery(uint256[] memory _expirationTimes, uint256[] memory _totalStakingAmounts, address[] memory _customerAddresses) public payable returns (uint256[] memory) {
5454
uint256[] memory agreementIds = new uint256[](_customerAddresses.length);
5555
for (uint256 i = 0; i < _customerAddresses.length; i++) {
56-
uint256 agreementId = _createAgreement(_titles[i], _expirationTimes[i], _totalStakingAmounts[i]);
56+
uint256 agreementId = _createAgreement(_expirationTimes[i], _totalStakingAmounts[i]);
5757
_addVendorParty(agreementId, msg.sender);
5858
_addCustomerParty(agreementId, _customerAddresses[i]);
5959
_signAgreement(agreementId);
6060
stakeAgreement(agreementId, _totalStakingAmounts[i]);
6161
contractly.lockAgreement(agreementId);
6262
agreementIds[i] = agreementId;
6363
}
64-
emit BatchDeliveryCreated(_titles, _expirationTimes, _totalStakingAmounts, _customerAddresses);
64+
emit BatchDeliveryCreated(_expirationTimes, _totalStakingAmounts, _customerAddresses);
6565
return agreementIds;
6666
}
6767

@@ -71,7 +71,7 @@ contract Delivery {
7171
}
7272
contractly.stakeAgreement{ value: _amount }(_agreementId, msg.sender);
7373
// Check if all parties have staked to automatically lock the agreement
74-
(,,,,,,,, address[] memory parties) = getAgreementDetails(_agreementId);
74+
(,,,,,,, address[] memory parties) = getAgreementDetails(_agreementId);
7575
bool allPartiesStaked = true;
7676
for (uint256 i = 0; i < parties.length; i++) {
7777
if (contractly.stakedFunds(_agreementId, parties[i]) == 0) {
@@ -89,34 +89,26 @@ contract Delivery {
8989
}
9090

9191
function breachAgreement(uint256 _agreementId, address _breachingParty) public {
92-
console.log("breaching party", _breachingParty);
93-
console.log("agreement id", _agreementId);
94-
console.log("status", uint256(contractly.getAgreementStatus(_agreementId)));
95-
console.log("party count", contractly.getPartyCount(_agreementId));
96-
console.log("party address at index 0", contractly.getPartyAddressAtIndex(_agreementId, 0));
97-
console.log("party address at index 1", contractly.getPartyAddressAtIndex(_agreementId, 1));
98-
console.log("party stake amount at index 0", contractly.getPartyStakeAmount(_agreementId, contractly.getPartyAddressAtIndex(_agreementId, 0)));
99-
console.log("party stake amount at index 1", contractly.getPartyStakeAmount(_agreementId, contractly.getPartyAddressAtIndex(_agreementId, 1)));
10092
contractly.breachAgreement(_agreementId, _breachingParty);
93+
}
10194

102-
console.log("After breach");
103-
console.log("breaching party", _breachingParty);
104-
console.log("agreement id", _agreementId);
105-
console.log("status", uint256(contractly.getAgreementStatus(_agreementId)));
106-
console.log("party count", contractly.getPartyCount(_agreementId));
107-
console.log("party address at index 0", contractly.getPartyAddressAtIndex(_agreementId, 0));
108-
console.log("party address at index 1", contractly.getPartyAddressAtIndex(_agreementId, 1));
109-
console.log("party stake amount at index 0", contractly.getPartyStakeAmount(_agreementId, contractly.getPartyAddressAtIndex(_agreementId, 0)));
110-
console.log("party stake amount at index 1", contractly.getPartyStakeAmount(_agreementId, contractly.getPartyAddressAtIndex(_agreementId, 1)));
95+
function checkDeliveryStatus(uint256 _agreementId) public {
96+
if(true){
97+
fulfillAgreement(_agreementId);
98+
}
99+
else{
100+
breachAgreement(_agreementId, msg.sender);
101+
}
102+
lastAutomationUpdate = block.timestamp;
111103
}
112104

113105
// ======== Internal Functions ========
114106

115-
function _createAgreement(string memory _title, uint256 _expirationTime, uint256 _totalStakingAmount) internal returns (uint256) {
107+
function _createAgreement(uint256 _expirationTime, uint256 _totalStakingAmount) internal returns (uint256) {
116108
// Create the agreement in Contractly
117-
uint256 agreementId = contractly.createAgreement(_title, msg.sender, _expirationTime, _totalStakingAmount);
109+
uint256 agreementId = contractly.createAgreement(msg.sender, _expirationTime, _totalStakingAmount);
118110

119-
emit AgreementCreated(agreementId, _title, msg.sender);
111+
emit AgreementCreated(agreementId, msg.sender);
120112

121113
return agreementId;
122114
}
@@ -139,11 +131,15 @@ contract Delivery {
139131

140132
// ======== Getters ========
141133

142-
function getAgreementDetails(uint256 _agreementId) public view returns (uint256 id, string memory title, address creator, uint256 creationTime, uint256 expirationTime, uint256 disputeWindowDuration, uint256 totalStakingAmount, Contractly.AgreementStatus status, address[] memory partyAddresses) {
134+
function getAgreementDetails(uint256 _agreementId) public view returns (uint256 id, address creator, uint256 creationTime, uint256 expirationTime, uint256 disputeWindowDuration, uint256 totalStakingAmount, Contractly.AgreementStatus status, address[] memory partyAddresses) {
143135
return contractly.getAgreement(_agreementId);
144136
}
145137

146138
function getHasVendorAssigned(uint256 _agreementId) public view returns (bool) {
147139
return hasVendorAssigned[_agreementId];
148140
}
141+
142+
function getLastAutomationUpdate() public view returns (uint256) {
143+
return lastAutomationUpdate;
144+
}
149145
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.24;
3+
4+
import {IDelivery} from "./Interface/IDelivery.sol";
5+
6+
contract GelatoFunctions {
7+
// State variable to store the last update timestamp
8+
IDelivery private delivery;
9+
10+
constructor(address _deliveryAddress) {
11+
delivery = IDelivery(_deliveryAddress);
12+
}
13+
// Event to emit when an update occurs
14+
event Updated(uint256 timestamp);
15+
16+
function checker() external view returns (bool, bytes memory) {
17+
uint256 lastUpdate = delivery.getLastAutomationUpdate();
18+
if (block.timestamp < lastUpdate + 5 minutes) {
19+
return (false, bytes("Not enough time has passed since the last update"));
20+
}
21+
bytes memory execPayload = abi.encodeCall(IDelivery.checkDeliveryStatus, (1));
22+
return (true, execPayload);
23+
}
24+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.24;
3+
4+
interface IDelivery {
5+
function getLastAutomationUpdate() external view returns (uint256);
6+
function updateLastUpdate() external;
7+
function createDelivery(string memory _title, uint256 _expirationTime, uint256 _totalStakingAmount, address _customerAddress) external payable returns (uint256);
8+
function createBatchDelivery(string[] memory _titles, uint256[] memory _expirationTimes, uint256[] memory _totalStakingAmounts, address[] memory _customerAddresses) external payable returns (uint256[] memory);
9+
function fulfillAgreement(uint256 _agreementId) external;
10+
function breachAgreement(uint256 _agreementId, address _breachingParty) external;
11+
function checkDeliveryStatus(uint256 _agreementId) external;
12+
}

packages/foundry/foundry.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ scrollSepolia = "https://sepolia-rpc.scroll.io"
2727
scroll = "https://rpc.scroll.io"
2828
pgn = "https://rpc.publicgoods.network"
2929
pgnTestnet = "https://sepolia.publicgoods.network"
30+
monadTestnet = "https://testnet-rpc.monad.xyz/"
3031

3132

3233
[etherscan]
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.19;
3+
4+
import { Script } from "forge-std/Script.sol";
5+
import { Contractly } from "../contracts/Contractly.sol";
6+
import { Delivery } from "../contracts/Delivery.sol";
7+
import { GelatoFunctions } from "../contracts/GelatoFunctions.sol";
8+
9+
contract DeployFoundry is Script {
10+
function run() external {
11+
vm.startBroadcast();
12+
// Contractly contractly = new Contractly(msg.sender);
13+
Delivery delivery = new Delivery(0xdC2A123491136132F0AC0Ec9d2e6C96Eb4c2CB9D);
14+
// new GelatoFunctions(0xA5140205d3C34eC7397E202c581FF5984dd0Bc3D);
15+
vm.stopBroadcast();
16+
}
17+
}

0 commit comments

Comments
 (0)