Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // SPDX-License-Identifier: MIT
- pragma solidity ^0.8.0;
- contract Escrow {
- address public buyer;
- address public seller;
- address public arbitrator;
- uint256 public depositAmount;
- bool public isBuyerConfirmed;
- bool public isSellerConfirmed;
- bool private locked;
- uint256 public transactionFeePercent = 5; // Larger fee, 5%
- enum EscrowState { NOT_INITIATED, AWAITING_CONFIRMATION, COMPLETE, DISPUTE }
- EscrowState public currentState;
- constructor(address _seller, address _arbitrator) {
- buyer = msg.sender;
- seller = _seller;
- arbitrator = _arbitrator;
- currentState = EscrowState.NOT_INITIATED;
- locked = false;
- }
- modifier onlyBuyer() {
- require(msg.sender == buyer, "Only the buyer can call this function.");
- _;
- }
- modifier onlyArbitrator() {
- require(msg.sender == arbitrator, "Only the arbitrator can call this function.");
- _;
- }
- modifier inState(EscrowState state) {
- require(currentState == state, "Invalid escrow state for this action.");
- _;
- }
- modifier noReentrancy() {
- require(!locked, "Reentrant call detected.");
- locked = true;
- _;
- locked = false;
- }
- function depositFunds() external payable onlyBuyer inState(EscrowState.NOT_INITIATED) {
- require(msg.value > 0, "Deposit amount must be greater than 0.");
- depositAmount = msg.value;
- currentState = EscrowState.AWAITING_CONFIRMATION;
- }
- function confirmReceipt() external onlyBuyer inState(EscrowState.AWAITING_CONFIRMATION) {
- isBuyerConfirmed = true;
- completeTransaction();
- }
- function releaseFunds() external inState(EscrowState.AWAITING_CONFIRMATION) noReentrancy {
- require(isBuyerConfirmed, "Buyer must confirm receipt before funds are released.");
- require(msg.sender == buyer || msg.sender == arbitrator, "Only buyer or arbitrator can release funds.");
- _withdraw(seller, depositAmount);
- currentState = EscrowState.COMPLETE;
- }
- function raiseDispute() external onlyBuyer inState(EscrowState.AWAITING_CONFIRMATION) {
- require(!isBuyerConfirmed, "Cannot raise dispute after confirming receipt.");
- currentState = EscrowState.DISPUTE;
- }
- function resolveDispute(bool refundBuyer) external onlyArbitrator inState(EscrowState.DISPUTE) noReentrancy {
- require(currentState == EscrowState.DISPUTE, "Cannot resolve dispute in the current state.");
- require(buyer != address(0) && seller != address(0), "Invalid parties involved.");
- if (refundBuyer) {
- _withdraw(buyer, depositAmount);
- } else {
- _withdraw(seller, depositAmount);
- }
- currentState = EscrowState.COMPLETE;
- }
- function cancelEscrow() external onlyBuyer inState(EscrowState.NOT_INITIATED) noReentrancy {
- _withdraw(buyer, address(this).balance);
- currentState = EscrowState.COMPLETE;
- }
- function getContractBalance() external view returns (uint256) {
- return address(this).balance;
- }
- function _withdraw(address recipient, uint256 amount) private {
- require(address(this).balance >= amount, "Insufficient contract balance.");
- uint256 fee = (amount * transactionFeePercent) / 100;
- uint256 amountAfterFee = amount - fee;
- require(fee > 0, "Fee must be greater than 0.");
- (bool feeSuccess, ) = payable(arbitrator).call{value: fee}();
- require(feeSuccess, "Transaction fee transfer failed.");
- (bool success, ) = payable(recipient).call{value: amountAfterFee}();
- require(success, "Transfer failed.");
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment