Solidity API

JobEventData

struct JobEventData {
  uint8 type_;
  bytes address_;
  bytes data_;
  uint32 timestamp_;
}

JobEventType

enum JobEventType {
  Created,
  Taken,
  Paid,
  Updated,
  Signed,
  Completed,
  Delivered,
  Closed,
  Reopened,
  Rated,
  Refunded,
  Disputed,
  Arbitrated,
  ArbitrationRefused,
  WhitelistedWorkerAdded,
  WhitelistedWorkerRemoved,
  CollateralWithdrawn,
  WorkerMessage,
  OwnerMessage
}

JobArbitrator

struct JobArbitrator {
  address address_;
  bytes publicKey;
  string name;
  string bio;
  string avatar;
  uint16 fee;
  uint16 settledCount;
  uint16 refusedCount;
}

User

struct User {
  address address_;
  bytes publicKey;
  string name;
  string bio;
  string avatar;
  uint16 reputationUp;
  uint16 reputationDown;
}

UserRating

Stores current average user's rating and number of reviews so it can be updated with every new review

struct UserRating {
  uint16 averageRating;
  uint256 numberOfReviews;
}

Review

struct Review {
  address reviewer;
  uint256 jobId;
  uint8 rating;
  string text;
  uint32 timestamp;
}

RATING_MIN

uint8 RATING_MIN

RATING_MAX

uint8 RATING_MAX

MarketplaceDataV1

MarketplaceAddressChanged

event MarketplaceAddressChanged(address marketplaceAddress)

JobEvent

event JobEvent(uint256 jobId, struct JobEventData eventData)

UserRegistered

event UserRegistered(address addr, bytes pubkey, string name, string bio, string avatar)

UserUpdated

event UserUpdated(address addr, string name, string bio, string avatar)

ArbitratorRegistered

event ArbitratorRegistered(address addr, bytes pubkey, string name, string bio, string avatar, uint16 fee)

ArbitratorUpdated

event ArbitratorUpdated(address addr, string name, string bio, string avatar)

marketplace

contract MarketplaceV1 marketplace

jobEvents

mapping(uint256 => struct JobEventData[]) jobEvents

users

mapping(address => struct User) users

userAddresses

address[] userAddresses

arbitrators

mapping(address => struct JobArbitrator) arbitrators

arbitratorAddresses

address[] arbitratorAddresses

userRatings

mapping(address => struct UserRating) userRatings

userReviews

mapping(address => struct Review[]) userReviews

meceTags

mapping(string => string) meceTags

__gap

uint256[41] __gap

onlyMarketplace

modifier onlyMarketplace()

constructor

constructor() public

initialize

function initialize(address marketplace_) public

Initialize contract

For upgradeable contracts this function necessary

Parameters

NameTypeDescription
marketplace_addressAddress of marketplace

publishJobEvent

function publishJobEvent(uint256 jobId_, struct JobEventData event_) public

eventsLength

function eventsLength(uint256 jobId_) public view returns (uint256)

jobsLength

function jobsLength() public view returns (uint256)

getJobs

function getJobs(uint256 index_, uint256 limit_) public view returns (struct JobPost[])

getJob

function getJob(uint256 jobId_) public view returns (struct JobPost)

getEvents

function getEvents(uint256 jobId_, uint256 index_, uint256 limit_) public view returns (struct JobEventData[])

checkUserParams

function checkUserParams(string name_, string bio_, string avatar_) internal pure

registerUser

function registerUser(bytes pubkey_, string name_, string bio_, string avatar_) public

updateUser

function updateUser(string name_, string bio_, string avatar_) public

userRegistered

function userRegistered(address address_) public view returns (bool)

userRefunded

function userRefunded(address address_) public

userDelivered

function userDelivered(address address_) public

usersLength

function usersLength() public view returns (uint256)

getUsers

function getUsers(uint256 index_, uint256 limit_) public view returns (struct User[])

publicKeys

function publicKeys(address userAddress_) public view returns (bytes)

getUser

function getUser(address userAddress_) public view returns (struct User)

registerArbitrator

function registerArbitrator(bytes pubkey_, string name_, string bio_, string avatar_, uint16 fee_) public

updateArbitrator

function updateArbitrator(string name_, string bio_, string avatar_) public

arbitratorRefused

function arbitratorRefused(address address_) public

arbitratorSettled

function arbitratorSettled(address address_) public

arbitratorRegistered

function arbitratorRegistered(address address_) public view returns (bool)

getArbitratorFee

function getArbitratorFee(address address_) public view returns (uint16)

arbitratorsLength

function arbitratorsLength() public view returns (uint256)

getArbitrators

function getArbitrators(uint256 index_, uint256 limit_) public view returns (struct JobArbitrator[])

getArbitrator

function getArbitrator(address arbitratorAddress_) public view returns (struct JobArbitrator)

updateUserRating

function updateUserRating(address userAddress_, uint8 reviewRating_) public

getUserRating

function getUserRating(address userAddress_) public view returns (struct UserRating)

readMeceTag

function readMeceTag(string shortForm) public view returns (string)

updateMeceTag

function updateMeceTag(string shortForm, string longForm) public

removeMeceTag

function removeMeceTag(string shortForm) public

addReview

function addReview(address target_, address reviewer_, uint256 jobId_, uint8 rating_, string text_) public

getReviews

function getReviews(address target_, uint256 index_, uint256 limit_) public view returns (struct Review[])

JobState

enum JobState {
  Open,
  Taken,
  Closed
}

_24_HRS

uint32 _24_HRS

JobRoles

struct JobRoles {
  address creator;
  address arbitrator;
  address worker;
}

JobPost

struct JobPost {
  uint8 state;
  bool whitelistWorkers;
  struct JobRoles roles;
  string title;
  string[] tags;
  bytes32 contentHash;
  bool multipleApplicants;
  uint256 amount;
  address token;
  uint32 timestamp;
  uint32 maxTime;
  string deliveryMethod;
  uint256 collateralOwed;
  uint256 escrowId;
  bytes32 resultHash;
  uint8 rating;
  bool disputed;
}

MarketplaceV1

marketplaceData

contract MarketplaceDataV1 marketplaceData

version

uint256 version

jobs

struct JobPost[] jobs

whitelistWorkers

mapping(uint256 => mapping(address => bool)) whitelistWorkers

unicrowAddress

address unicrowAddress

unicrowDisputeAddress

address unicrowDisputeAddress

unicrowArbitratorAddress

address unicrowArbitratorAddress

treasuryAddress

address treasuryAddress

unicrowMarketplaceFee

uint16 unicrowMarketplaceFee

__gap

uint256[41] __gap

onlyJobCreator

modifier onlyJobCreator(uint256 jobId_)

onlyWorker

modifier onlyWorker(uint256 jobId_)

onlyCreatorOrWorker

modifier onlyCreatorOrWorker(uint256 jobId_)

onlyArbitrator

modifier onlyArbitrator(uint256 jobId_)

VersionChanged

event VersionChanged(uint256 version)

MarketplaceDataAddressChanged

event MarketplaceDataAddressChanged(address marketplaceDataAddress)

UnicrowAddressesChanged

event UnicrowAddressesChanged(address unicrowAddress, address unicrowDisputeAddress, address unicrowArbitratorAddress)

UnicrowMarketplaceFeeChanged

event UnicrowMarketplaceFeeChanged(uint16 unicrowMarketplaceFee)

TreasuryAddressChanged

event TreasuryAddressChanged(address treasuryAddress)

constructor

constructor() public

initialize

function initialize(address unicrowAddress_, address unicrowDisputeAddress_, address unicrowArbitratorAddress_, address treasuryAddress_, uint16 unicrowMarketplaceFee_) public

Initialize contract

For upgradeable contracts this function necessary

Parameters

NameTypeDescription
unicrowAddress_addressAddress of Unicrow contract
unicrowDisputeAddress_addressAddress of UnicrowDispute contract
unicrowArbitratorAddress_addressAddress of UnicrowArbitrator contract
treasuryAddress_addressAddress which will collect this marketplace fees, better not to set it to address(this) to not mess up with collateral values
unicrowMarketplaceFee_uint16Fee for this marketplace in bips

setMarketplaceDataAddress

function setMarketplaceDataAddress(address marketplaceDataAddress_) public

setUnicrowMarketplaceFee

function setUnicrowMarketplaceFee(uint16 unicrowMarketplaceFee_) public

transferOwnership

function transferOwnership(address to_) public

Transfer ownership

Parameters

NameTypeDescription
to_addressAddress to transfer ownership to

pause

function pause() external

Pauses contract

unpause

function unpause() external

Unpauses contract

setVersion

function setVersion(uint256 version_) external

Set version

This is used for upgrades to inform miners of changes

Parameters

NameTypeDescription
version_uint256Version of contract

setTreasuryAddress

function setTreasuryAddress(address treasuryAddress_) public

updateUnicrowAddresses

function updateUnicrowAddresses(address unicrowAddress_, address unicrowDisputeAddress_, address unicrowArbitratorAddress_) public

jobsLength

function jobsLength() public view returns (uint256)

getJob

function getJob(uint256 jobId_) public view returns (struct JobPost)

publishJobEvent

function publishJobEvent(uint256 jobId_, struct JobEventData event_) internal

checkParams

function checkParams(string title_, string[] tags_, uint256 amount_, address arbitrator_, address creator_) internal view

publishJobPost

function publishJobPost(string title_, bytes32 contentHash_, bool multipleApplicants_, string[] tags_, address token_, uint256 amount_, uint32 maxTime_, string deliveryMethod_, address arbitrator_, address[] allowedWorkers_) public returns (uint256)

Publish a new job post To assign the job to a specific worker, set multipleApplicants_ to false and add the worker to the allowedWorkers_. In such a case, title and description can be encrypted for the worker The function will request a collateral deposit in the amount_ and token_ from the caller. Great care should be taken both by job creator and worker accepting the job to verify that the reward token does not have side effects, e.g. those of rebasing tokens. This can cause locked funds problem or lack of liquidity problem due to discrepancy in marketplace contract's state (stored amounts) and token contract's state (actual balance). This contract does not try to solve the potential problem of job creator and arbitrator colluding to profit from the worker. Platform users bare the responsibility of choosing the arbitrators and working with them. Maintaining a whitelist of trusted tokens and/or arbitrators does not appear to be a solution for two possible problems mentioned above for this marketplace, as it would empair the freedom of choice of the platform users and would require further maintenance work from contract owner/governing group.

Parameters

NameTypeDescription
title_stringjob title - must be not null
contentHash_bytes32short job description published on IPFS
multipleApplicants_booldo you want to select from multiple applicants or let the first one take the job?
tags_string[]labels to help the workers search for the job. Each job must have exactly one of the labels listed above, and any number of other labels
token_addresstoken in which you prefer to pay the job with - must be a valid ERC20 token, e.g. WETH
amount_uint256expected amount to pay for the job - must be greater than 0
maxTime_uint32maximum expected time (in sec) to deliver the job - must be greater than 0
deliveryMethod_stringpreferred method of delivery (e.g. "IPFS", "Courier")
arbitrator_addressaddress of an arbitrator preferred by the customer
allowedWorkers_address[]list of workers that can apply for the job. Leave empty if any worker can apply

updateJobPost

function updateJobPost(uint256 jobId_, string title_, bytes32 contentHash_, string[] tags_, uint256 amount_, uint32 maxTime_, address arbitrator_, bool whitelistWorkers_) public

updateJobWhitelist

function updateJobWhitelist(uint256 jobId_, address[] allowedWorkers_, address[] disallowedWorkers_) public

_updateJobWhitelist

function _updateJobWhitelist(uint256 jobId_, address[] allowedWorkers_, address[] disallowedWorkers_) internal

closeJob

function closeJob(uint256 jobId_) public

Close the job that hasn't been started. If it's been more than 24 hrs since the job was posted, the collateral will be automatically returned. Otherwise the buyer must withdraw the collateral separately.

withdrawCollateral

function withdrawCollateral(uint256 jobId_) public

Withdraw collateral from the closed job

reopenJob

function reopenJob(uint256 jobId_) public

postThreadMessage

function postThreadMessage(uint256 jobId_, bytes32 contentHash_, address recipient) public

takeJob

function takeJob(uint256 jobId_, bytes signature_) public

The worker takes the job, i.e. is ready to start working on it. The worker also cryptographically signs job parameters to prevent disputes about job specification. If this is FCFS job, the function may move money to the

Parameters

NameTypeDescription
jobId_uint256id of the job
signature_bytesworker's signature of all the job parameters

payStartJob

function payStartJob(uint256 jobId_, address worker_) public payable

Pay for a job so that the it gets started.

Parameters

NameTypeDescription
jobId_uint256ID of the job
worker_addressAn address of the worker selected for the job

deliverResult

function deliverResult(uint256 jobId_, bytes32 resultHash_) public

Information about the job delivery

Parameters

NameTypeDescription
jobId_uint256Id of the job
resultHash_bytes32e.g. IPFS url or a tracking no.

approveResult

function approveResult(uint256 jobId_, uint8 reviewRating_, string reviewText_) public

Buyer approves the result delivered by the seller, releases funds from the escrow, and optionally leaves a review.

Parameters

NameTypeDescription
jobId_uint256
reviewRating_uint81-5 (tbd) score of the worker. Set to 0 for no review
reviewText_stringOptional review text. Empty string for no text

review

function review(uint256 jobId_, uint8 reviewRating_, string reviewText_) public

_refund

function _refund(uint256 jobId_, bool byWorker) internal

Worker refunds the buyer and switches the job back to non-started state

refund

function refund(uint256 jobId_) public

Worker refunds the buyer and switches the job back to non-started state

dispute

function dispute(uint256 jobId_, bytes sessionKey_, bytes content_) public

Raise a dispute with the arbitrator. If the buyer is calling the dispute, the function will challenge the payment on Unicrow.

Parameters

NameTypeDescription
jobId_uint256
sessionKey_bytesEncrypted session key for the arbitrator to decrypt owner's and worker's messages
content_bytesEncrypted short description for the arbitrator

arbitrate

function arbitrate(uint256 jobId_, uint16 buyerShare_, uint16 workerShare_, bytes32 reasonHash_) public

decide on a dispute about the job.

Parameters

NameTypeDescription
jobId_uint256
buyerShare_uint16how much of the payment should be refunded back to the buyer (in BPS)
workerShare_uint16how much of the payment should be released to the worker (in BPS)
reasonHash_bytes32reason for arbitrator's decision (encrypted for all three parties)

refuseArbitration

function refuseArbitration(uint256 jobId_) public

If an arbitrator has been included in a job they're not comfortable with, they can remove themselves. If the job has been started and paid into the escrow, the escrow will be fully refunded TBD: we discussed that the in this case, the arbitrator fee should be refunded as well so t hat the arbitrator doesn't keep funds from potentially illicit transactions. However, perhaps it might be better for the arbitrator to keep the fee to prevent spam? More in Notion

encodeString

function encodeString(string str) internal pure returns (bytes)

encodeBytes

function encodeBytes(bytes b) internal pure returns (bytes)

encodeStringArray

function encodeStringArray(string[] arr) internal pure returns (bytes)

encodeAddressArray

function encodeAddressArray(address[] arr) internal pure returns (bytes)

_100_PCT_IN_BIPS

uint16 _100_PCT_IN_BIPS

WHO_BUYER

uint8 WHO_BUYER

WHO_SELLER

uint8 WHO_SELLER

WHO_MARKETPLACE

uint8 WHO_MARKETPLACE

WHO_PROTOCOL

uint8 WHO_PROTOCOL

WHO_ARBITRATOR

uint8 WHO_ARBITRATOR

Escrow

This is how information about each escrow is stored int he main contract, mapped to escrowId

struct Escrow {
  address buyer;
  uint64 challengeExtension;
  address seller;
  uint64 challengePeriodStart;
  address marketplace;
  uint256 marketplaceFee;
  uint64 challengePeriodEnd;
  address currency;
  uint16 claimed;
  int16[2] consensus;
  uint16[4] split;
  uint256 amount;
  string paymentReference;
}

EscrowInput

Escrow parameters to be sent along with the deposit

struct EscrowInput {
  address buyer;
  address seller;
  address marketplace;
  uint16 marketplaceFee;
  address currency;
  uint32 challengePeriod;
  uint32 challengeExtension;
  uint256 amount;
  string paymentReference;
}

Arbitrator

Information about arbitrator proposed or assigned to an escrow. If both buyerConsensus and sellerConsensus are 1, the arbitrator is assigned, otherwise it's only been proposed by the party that has 1

struct Arbitrator {
  address arbitrator;
  uint16 arbitratorFee;
  bool sellerConsensus;
  bool buyerConsensus;
  bool arbitrated;
}

Settlement

Stores information about settlement, mapped to escrowId in UnicrowDispute contract

struct Settlement {
  address latestSettlementOfferBy;
  uint16[2] latestSettlementOffer;
}

Token

Information about the token used in the payment is returned in this structure

struct Token {
  address address_;
  uint8 decimals;
  string symbol;
}

Data

Superstructure that includes all the information relevant to an escrow

struct Data {
  struct Escrow escrow;
  struct Arbitrator arbitrator;
  struct Settlement settlement;
  struct Token token;
}

abs8

function abs8(int16 x) internal pure returns (int16)