irongit

refactor(contracts): update the contract to latest solidity contract

huncholanehuncholaneauthored
parent 0e7bf08commit db55fb013972c6e22e67e5b13dea16739d56e19fBrowse files

2 files changed, +193 -68

+68-30contracts/Factory.sol
@@ -1,41 +1,79 @@
1-pragma solidity >=0.4.25 <0.6.0;
1+// SPDX-License-Identifier: MIT
2+pragma solidity ^0.8.20;
23
34 import "./HomeTransaction.sol";
45
56 contract Factory {
6- HomeTransaction[] contracts;
7+ HomeTransaction[] public contracts;
78
8- function create(
9+ mapping(address => HomeTransaction[]) public contractsByRealtor;
10+ mapping(address => HomeTransaction[]) public contractsBySeller;
11+ mapping(address => HomeTransaction[]) public contractsByBuyer;
12+
13+ event ContractCreated(
14+ address indexed contractAddress,
15+ address indexed realtor,
16+ address indexed seller,
17+ address buyer,
18+ uint price
19+ );
20+
21+ function create(
922 string memory _address,
1023 string memory _zip,
1124 string memory _city,
1225 uint _realtorFee,
1326 uint _price,
1427 address payable _seller,
15- address payable _buyer) public returns(HomeTransaction homeTransaction) {
16- homeTransaction = new HomeTransaction(
17- _address,
18- _zip,
19- _city,
20- _realtorFee,
21- _price,
22- msg.sender,
23- _seller,
24- _buyer);
25- contracts.push(homeTransaction);
26- }
27-
28- function getInstance(uint index) public view returns (HomeTransaction instance) {
29- require(index < contracts.length, "index out of range");
30-
31- instance = contracts[index];
32- }
33-
34- function getInstances() public view returns (HomeTransaction[] memory instances) {
35- instances = contracts;
36- }
37-
38- function getInstanceCount() public view returns (uint count) {
39- count = contracts.length;
40- }
41-}
28+ address payable _buyer
29+ ) external returns (HomeTransaction homeTransaction) {
30+ homeTransaction = new HomeTransaction(
31+ _address,
32+ _zip,
33+ _city,
34+ _realtorFee,
35+ _price,
36+ payable(msg.sender), // realtor is the caller
37+ _seller,
38+ _buyer
39+ );
40+
41+ contracts.push(homeTransaction);
42+ contractsByRealtor[msg.sender].push(homeTransaction);
43+ contractsBySeller[_seller].push(homeTransaction);
44+ contractsByBuyer[_buyer].push(homeTransaction);
45+
46+ emit ContractCreated(
47+ address(homeTransaction),
48+ msg.sender,
49+ _seller,
50+ _buyer,
51+ _price
52+ );
53+ }
54+
55+ function getInstance(uint index) external view returns (HomeTransaction) {
56+ require(index < contracts.length, "Index out of range");
57+ return contracts[index];
58+ }
59+
60+ function getInstances() external view returns (HomeTransaction[] memory) {
61+ return contracts;
62+ }
63+
64+ function getInstanceCount() external view returns (uint) {
65+ return contracts.length;
66+ }
67+
68+ function getContractsByRealtor(address realtor) external view returns (HomeTransaction[] memory) {
69+ return contractsByRealtor[realtor];
70+ }
71+
72+ function getContractsBySeller(address seller) external view returns (HomeTransaction[] memory) {
73+ return contractsBySeller[seller];
74+ }
75+
76+ function getContractsByBuyer(address buyer) external view returns (HomeTransaction[] memory) {
77+ return contractsByBuyer[buyer];
78+ }
79+}
+125-38contracts/HomeTransaction.sol
@@ -1,9 +1,11 @@
1-pragma solidity >=0.4.25 <0.6.0;
1+// SPDX-License-Identifier: MIT
2+pragma solidity ^0.8.20;
23
34 contract HomeTransaction {
45 // Constants
5- uint constant timeBetweenDepositAndFinalization = 5 minutes;
6- uint constant depositPercentage = 10;
6+ uint constant FINALIZATION_WINDOW = 5 minutes;
7+ uint constant MIN_DEPOSIT_PERCENTAGE = 10;
8+ uint constant MAX_DEPOSIT_PERCENTAGE = 100;
79
810 enum ContractState {
911 WaitingSellerSignature,
@@ -11,10 +13,10 @@ contract HomeTransaction {
1113 WaitingRealtorReview,
1214 WaitingFinalization,
1315 Finalized,
14- Rejected }
16+ Rejected
17+ }
1518 ContractState public contractState = ContractState.WaitingSellerSignature;
1619
17-
1820 // Roles acting on contract
1921 address payable public realtor;
2022 address payable public seller;
@@ -33,7 +35,14 @@ contract HomeTransaction {
3335
3436 // Set when realtor reviews closing conditions
3537 enum ClosingConditionsReview { Pending, Accepted, Rejected }
36- ClosingConditionsReview closingConditionsReview = ClosingConditionsReview.Pending;
38+ ClosingConditionsReview public closingConditionsReview = ClosingConditionsReview.Pending;
39+
40+ // Events
41+ event SellerSigned(address indexed seller);
42+ event BuyerSignedAndDeposited(address indexed buyer, uint deposit);
43+ event RealtorReviewed(address indexed realtor, bool accepted);
44+ event TransactionFinalized(address indexed buyer, uint totalPrice);
45+ event TransactionWithdrawn(address indexed initiator);
3746
3847 constructor(
3948 string memory _address,
@@ -43,8 +52,12 @@ contract HomeTransaction {
4352 uint _price,
4453 address payable _realtor,
4554 address payable _seller,
46- address payable _buyer) public {
47- require(_price >= _realtorFee, "Price needs to be more than realtor fee!");
55+ address payable _buyer
56+ ) {
57+ require(_price >= _realtorFee, "Price must be >= realtor fee");
58+ require(_realtor != address(0), "Invalid realtor address");
59+ require(_seller != address(0), "Invalid seller address");
60+ require(_buyer != address(0), "Invalid buyer address");
4861
4962 realtor = _realtor;
5063 seller = _seller;
@@ -56,32 +69,61 @@ contract HomeTransaction {
5669 realtorFee = _realtorFee;
5770 }
5871
59- function sellerSignContract() public payable {
60- require(seller == msg.sender, "Only seller can sign contract");
72+ modifier onlySeller() {
73+ require(msg.sender == seller, "Only seller can call");
74+ _;
75+ }
6176
62- require(contractState == ContractState.WaitingSellerSignature, "Wrong contract state");
77+ modifier onlyBuyer() {
78+ require(msg.sender == buyer, "Only buyer can call");
79+ _;
80+ }
6381
64- contractState = ContractState.WaitingBuyerSignature;
82+ modifier onlyRealtor() {
83+ require(msg.sender == realtor, "Only realtor can call");
84+ _;
6585 }
6686
67- function buyerSignContractAndPayDeposit() public payable {
68- require(buyer == msg.sender, "Only buyer can sign contract");
87+ modifier inState(ContractState _state) {
88+ require(contractState == _state, "Invalid contract state");
89+ _;
90+ }
6991
70- require(contractState == ContractState.WaitingBuyerSignature, "Wrong contract state");
92+ function sellerSignContract()
93+ external
94+ onlySeller
95+ inState(ContractState.WaitingSellerSignature)
96+ {
97+ contractState = ContractState.WaitingBuyerSignature;
98+ emit SellerSigned(msg.sender);
99+ }
71100
72- require(msg.value >= price*depositPercentage/100 && msg.value <= price, "Buyer needs to deposit between 10% and 100% to sign contract");
101+ function buyerSignContractAndPayDeposit()
102+ external
103+ payable
104+ onlyBuyer
105+ inState(ContractState.WaitingBuyerSignature)
106+ {
107+ uint minDeposit = (price * MIN_DEPOSIT_PERCENTAGE) / 100;
108+ uint maxDeposit = (price * MAX_DEPOSIT_PERCENTAGE) / 100;
73109
74- contractState = ContractState.WaitingRealtorReview;
110+ require(
111+ msg.value >= minDeposit && msg.value <= maxDeposit,
112+ "Deposit must be 10-100% of price"
113+ );
75114
76115 deposit = msg.value;
77- finalizeDeadline = now + timeBetweenDepositAndFinalization;
78- }
79-
80- function realtorReviewedClosingConditions(bool accepted) public {
81- require(realtor == msg.sender, "Only realtor can review closing conditions");
116+ finalizeDeadline = block.timestamp + FINALIZATION_WINDOW;
117+ contractState = ContractState.WaitingRealtorReview;
82118
83- require(contractState == ContractState.WaitingRealtorReview, "Wrong contract state");
119+ emit BuyerSignedAndDeposited(msg.sender, msg.value);
120+ }
84121
122+ function realtorReviewClosingConditions(bool accepted)
123+ external
124+ onlyRealtor
125+ inState(ContractState.WaitingRealtorReview)
126+ {
85127 if (accepted) {
86128 closingConditionsReview = ClosingConditionsReview.Accepted;
87129 contractState = ContractState.WaitingFinalization;
@@ -89,31 +131,76 @@ contract HomeTransaction {
89131 closingConditionsReview = ClosingConditionsReview.Rejected;
90132 contractState = ContractState.Rejected;
91133
92- buyer.transfer(deposit);
134+ // Refund buyer's deposit
135+ (bool success, ) = buyer.call{value: deposit}("");
136+ require(success, "Refund failed");
93137 }
138+
139+ emit RealtorReviewed(msg.sender, accepted);
94140 }
95141
96- function buyerFinalizeTransaction() public payable {
97- require(buyer == msg.sender, "Only buyer can finalize transaction");
142+ function buyerFinalizeTransaction()
143+ external
144+ payable
145+ onlyBuyer
146+ inState(ContractState.WaitingFinalization)
147+ {
148+ require(
149+ msg.value + deposit == price,
150+ "Must pay remaining balance"
151+ );
98152
99- require(contractState == ContractState.WaitingFinalization, "Wrong contract state");
153+ contractState = ContractState.Finalized;
100154
101- require(msg.value + deposit == price, "Buyer needs to pay the rest of the cost to finalize transaction");
155+ // Pay seller (price minus realtor fee)
156+ (bool sellerPaid, ) = seller.call{value: price - realtorFee}("");
157+ require(sellerPaid, "Seller payment failed");
102158
103- contractState = ContractState.Finalized;
159+ // Pay realtor
160+ (bool realtorPaid, ) = realtor.call{value: realtorFee}("");
161+ require(realtorPaid, "Realtor payment failed");
104162
105- seller.transfer(price-realtorFee);
106- realtor.transfer(realtorFee);
163+ emit TransactionFinalized(msg.sender, price);
107164 }
108165
109- function anyWithdrawFromTransaction() public {
110- require(buyer == msg.sender || finalizeDeadline <= now, "Only buyer can withdraw before transaction deadline");
111-
112- require(contractState == ContractState.WaitingFinalization, "Wrong contract state");
166+ function withdrawFromTransaction()
167+ external
168+ inState(ContractState.WaitingFinalization)
169+ {
170+ require(
171+ msg.sender == buyer || block.timestamp >= finalizeDeadline,
172+ "Only buyer can withdraw before deadline"
173+ );
113174
114175 contractState = ContractState.Rejected;
115176
116- seller.transfer(deposit-realtorFee);
117- realtor.transfer(realtorFee);
177+ // Seller gets deposit minus realtor fee
178+ (bool sellerPaid, ) = seller.call{value: deposit - realtorFee}("");
179+ require(sellerPaid, "Seller payment failed");
180+
181+ // Realtor still gets fee
182+ (bool realtorPaid, ) = realtor.call{value: realtorFee}("");
183+ require(realtorPaid, "Realtor payment failed");
184+
185+ emit TransactionWithdrawn(msg.sender);
186+ }
187+
188+ // View functions
189+ function getContractDetails() external view returns (
190+ string memory _homeAddress,
191+ string memory _zip,
192+ string memory _city,
193+ uint _price,
194+ uint _realtorFee,
195+ ContractState _state
196+ ) {
197+ return (homeAddress, zip, city, price, realtorFee, contractState);
198+ }
199+
200+ function getRemainingBalance() external view returns (uint) {
201+ if (contractState != ContractState.WaitingFinalization) {
202+ return 0;
203+ }
204+ return price - deposit;
118205 }
119-}
206+}