Skip to content

Commit

Permalink
feat: added escrow functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
OnahProsperity committed Sep 22, 2024
1 parent 9d79a41 commit 1dca9d6
Show file tree
Hide file tree
Showing 4 changed files with 613 additions and 0 deletions.
50 changes: 50 additions & 0 deletions contracts/Gateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity ^0.8.18;

import '@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol';
import '@openzeppelin/contracts/utils/cryptography/ECDSA.sol';

import {GatewaySettingManager} from './GatewaySettingManager.sol';
import {IGateway, IERC20} from './interfaces/IGateway.sol';
Expand All @@ -11,6 +12,7 @@ import {IGateway, IERC20} from './interfaces/IGateway.sol';
* @notice This contract serves as a gateway for creating orders and managing settlements.
*/
contract Gateway is IGateway, GatewaySettingManager, PausableUpgradeable {
using ECDSA for bytes32;
struct fee {
uint256 protocolFee;
uint256 liquidityProviderAmount;
Expand All @@ -20,6 +22,7 @@ contract Gateway is IGateway, GatewaySettingManager, PausableUpgradeable {
mapping(address => uint256) private _nonce;
uint256[50] private __gap;
mapping(address => mapping(address => uint256)) private balance;
mapping(bytes32 => bool) private processedOrders;

/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
Expand Down Expand Up @@ -247,6 +250,48 @@ contract Gateway is IGateway, GatewaySettingManager, PausableUpgradeable {
return true;
}

/** @dev See {deposit-IGateway}. */
function escrow(
bytes32 _orderId,
bytes memory _signature,
address _provider,
address _senderAddress,
address _token,
uint256 _amount
) external onlyAggregator isValidAmount(_amount) {
require(!processedOrders[_orderId], "Order already processed");
require(_provider != address(0), "Invalid provider address");
require(_senderAddress != address(0), "Invalid sender address");

// Verify signature
bytes32 messageHash = keccak256(abi.encodePacked(_orderId, _provider, _senderAddress, _token, _amount));
bytes32 ethSignedMessageHash = messageHash.toEthSignedMessageHash();
address recoveredAddress = ethSignedMessageHash.recover(_signature);
require(recoveredAddress == _provider, "Invalid signature");
// update transaction
uint256 _protocolFee = (_amount * protocolFeePercent) / MAX_BPS;
// uint256 sumAmount = _amount + _protocolFee;
// Check provider's balance,
// Note: There is no need for checks for token supported as the balance will be 0 if the token is not supported
require(balance[_token][_provider] >= _amount + _protocolFee, "Insufficient balance");

// Mark order as processed
processedOrders[_orderId] = true;

// Update balances
balance[_token][_provider] -= (_amount + _protocolFee);

// transfer to sender
IERC20(_token).transfer(_senderAddress, _amount);
if (_protocolFee != 0) {
// transfer protocol fee
IERC20(_token).transfer(treasuryAddress, _protocolFee);
}

// Emit event
emit Escrow(_provider, _senderAddress, _amount, _token, _orderId);
}

/* ##################################################################
VIEW CALLS
################################################################## */
Expand All @@ -270,4 +315,9 @@ contract Gateway is IGateway, GatewaySettingManager, PausableUpgradeable {
function getBalance(address _token, address _provider) external view returns (uint256) {
return balance[_token][_provider];
}

/** See {isOrderProcessed-IGateway} */
function isOrderProcessed(bytes32 _orderId) external view returns (bool) {
return processedOrders[_orderId];
}
}
35 changes: 35 additions & 0 deletions contracts/interfaces/IGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ interface IGateway {
*/
event Deposit(address indexed sender, address indexed token, uint256 indexed amount);

/**
* @dev Emitted when an escrow is made by a provider.
* @param provider The address of the provider.
* @param senderAddress The address of the sender.
* @param amount The address of the deposited token.
* @param token The amount of the deposit.
* @param orderId The ID of the order.
*/
event Escrow(address indexed provider, address indexed senderAddress, uint256 indexed amount, address token, bytes32 orderId);
/* ##################################################################
STRUCTS
################################################################## */
Expand Down Expand Up @@ -161,6 +170,25 @@ interface IGateway {
*/
function deposit(address _token, uint256 _amount) external returns (bool);


/**
* @notice Escrowed assets from provider to the sender.
* @param _orderId The ID of the transaction.
* @param _signature The signature of the provider.
* @param _provider The address of the provider.
* @param _senderAddress The address of the sender.
* @param _token The address of the asset.
* @param _amount The amount to be transferred.
*/
function escrow(
bytes32 _orderId,
bytes memory _signature,
address _provider,
address _senderAddress,
address _token,
uint256 _amount
) external;

/**
* @notice Checks if a token is supported by Gateway.
* @param _token The address of the token to check.
Expand Down Expand Up @@ -189,4 +217,11 @@ interface IGateway {
* @return uint256 The provider's balance.
*/
function getBalance(address _asset, address _provider) external view returns (uint256);

/**
* @notice Gets order processed status.
* @param _orderId The ID of the order.
* @return bool The order processed status.
*/
function isOrderProcessed(bytes32 _orderId) external view returns (bool);
}
Loading

0 comments on commit 1dca9d6

Please sign in to comment.