Skip to content

Commit

Permalink
refactor: enhance ErrandManager with status management and event emis…
Browse files Browse the repository at this point in the history
…sions
  • Loading branch information
Da-Colon committed Dec 31, 2024
1 parent 54b494d commit db2f32a
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 72 deletions.
95 changes: 33 additions & 62 deletions contracts/src/ErrandManager.sol
Original file line number Diff line number Diff line change
@@ -1,98 +1,69 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import {IErrandManager} from "./interfaces/IErrandManager.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";

/**
* Definitions:
* - Errantry: the business of running errands
* - Errand: a short task that needs to be done
* - Errand Runner: a person who runs errands
* - Errand Client: a person who requests errands to be run
*/

/**
* @title ErrandManager
* @author @Da-Colon
* @notice ErandManager is complimentary to the Errantry contract.
* @notice Functions must be called by the Errantry contract via the oracle.
*/
contract ErrandManager is IErrandManager, Ownable {
// @TODO decide if constant is the way to do go.
// uint8 constant STATUS_COMPLETED = 1 << 0; // 1 (binary 00000001)
// uint8 constant STATUS_PAID = 1 << 1; // 2 (binary 00000010)
// uint8 constant STATUS_CANCELLED = 1 << 2; // 4 (binary 00000100)
uint8 constant STATUS_COMPLETED = 1 << 0; // 1 (binary 00000001)
uint8 constant STATUS_PAID = 1 << 1; // 2 (binary 00000010)
uint8 constant STATUS_CANCELLED = 1 << 2; // 4 (binary 00000100)

event ErrandPosted(
uint256 indexed errandId,
address indexed client,
address indexed runner,
address paymentToken,
uint256 paymentAmount,
uint256 expires
);
mapping(uint256 => Errand) public errands;

constructor() Ownable(msg.sender) {}

/* >>>>>>>> errand runner functions <<<<<<< */

/* >>>>>>>> errand client functions <<<<<<< */
constructor() Ownable(msg.sender) {
// @todo do I care about checking the owner here?
}

/* >>>>>>>> oracle functions <<<<<<< */
function postNewErrand(
uint256 errandId,
address client,
uint256 expires,
address tokenAddress,
uint256 amount
) external onlyOwner {
function postNewErrand(uint256 errandId, address client, uint256 expires, address tokenAddress, uint256 amount)
external
onlyOwner
{
errands[errandId] = Errand({
errandId: errandId,
paymentToken: PaymentToken({
tokenAddress: tokenAddress,
amount: amount
}),
paymentToken: PaymentToken({tokenAddress: tokenAddress, amount: amount}),
runner: address(0),
expires: expires,
status: 0 // initialized at 0 (not completed, not paid, not cancelled)
});

emit ErrandPosted(
errandId,
client,
address(0),
tokenAddress,
amount,
expires
);
emit ErrandPosted(errandId, client, address(0), tokenAddress, amount, expires);
}

function updateErrandRunner(
uint256 errandId,
address runner
) external onlyOwner {
function updateErrandRunner(uint256 errandId, address runner) external onlyOwner {
errands[errandId].runner = runner;
}

function markErrandAsComplete(
IErrandManager _errandManager,
uint256 errandId
) external onlyOwner {}
function markErrandAsComplete(uint256 errandId) external onlyOwner {
require(_hasStatus(errandId, STATUS_COMPLETED), ErrandAlreadyCompleted());
_setStatus(errandId, STATUS_COMPLETED);
emit ErrandCompleted(errandId);
}

/* >>>>>>>> internal functions <<<<<<< */
function _setStatus(uint256 errandId, uint8 flag) internal {
errands[errandId].status |= flag;
function markErrandAsPaid(uint256 errandId) external onlyOwner {
require(_hasStatus(errandId, STATUS_COMPLETED), ErrandNotCompleted());
require(_hasStatus(errandId, STATUS_PAID), ErrandAlreadyPaid());
_setStatus(errandId, STATUS_PAID);
emit ErrandPaid(errandId);
}

function _clearStatus(uint256 errandId, uint8 flag) internal {
errands[errandId].status &= ~flag;
function cancelErrand(uint256 errandId) external onlyOwner {
require(!_hasStatus(errandId, STATUS_COMPLETED), ErrandAlreadyCompleted());
_setStatus(errandId, STATUS_CANCELLED);
emit ErrandCancelled(errandId);
}

function _setStatus(uint256 errandId, uint8 flag) private {
errands[errandId].status |= flag;
}

function _hasStatus(
uint256 errandId,
uint8 flag
) internal view returns (bool) {
function _hasStatus(uint256 errandId, uint8 flag) private view returns (bool) {
return (errands[errandId].status & flag) != 0;
}
}
42 changes: 32 additions & 10 deletions contracts/src/interfaces/IErrandManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,43 @@ interface IErrandManager {
address tokenAddress;
uint256 amount;
}

struct Errand {
uint256 errandId;
PaymentToken paymentToken; // the address of the runner, 0x0 if not yet assigned
PaymentToken paymentToken;
address runner;
uint256 expires; // the block number when the errand expires
uint8 status; // bitfield to store completed/paid/cancelled
uint256 expires;
uint8 status;
}

event ErrandPosted(
uint256 indexed errandId,
address indexed client,
address indexed runner,
address paymentToken,
uint256 paymentAmount,
uint256 expires
);

event ErrandRunnerUpdated(uint256 indexed errandId, address indexed runner);
event ErrandCompleted(uint256 indexed errandId);
event ErrandPaid(uint256 indexed errandId);
event ErrandCancelled(uint256 indexed errandId);

error ErrandAlreadyCompleted();
error ErrandNotCompleted();
error ErrandNotPaid();
error ErrandAlreadyPaid();
error ErrandAlreadyCancelled();

function postNewErrand(uint256 errandId, address client, uint256 expires, address tokenAddress, uint256 amount)
external;

function updateErrandRunner(uint256 errandId, address runner) external;

function postNewErrand(
uint256 errandId,
address client,
uint256 expires,
address tokenAddress,
uint256 amount
) external;
function markErrandAsComplete(uint256 errandId) external;

function markErrandAsPaid(uint256 errandId) external;

function cancelErrand(uint256 errandId) external;
}

0 comments on commit db2f32a

Please sign in to comment.