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
Name | Type | Description |
---|---|---|
marketplace_ | address | Address 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
Name | Type | Description |
---|---|---|
unicrowAddress_ | address | Address of Unicrow contract |
unicrowDisputeAddress_ | address | Address of UnicrowDispute contract |
unicrowArbitratorAddress_ | address | Address of UnicrowArbitrator contract |
treasuryAddress_ | address | Address which will collect this marketplace fees, better not to set it to address(this) to not mess up with collateral values |
unicrowMarketplaceFee_ | uint16 | Fee 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
Name | Type | Description |
---|---|---|
to_ | address | Address 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
Name | Type | Description |
---|---|---|
version_ | uint256 | Version 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
Name | Type | Description |
---|---|---|
title_ | string | job title - must be not null |
contentHash_ | bytes32 | short job description published on IPFS |
multipleApplicants_ | bool | do 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_ | address | token in which you prefer to pay the job with - must be a valid ERC20 token, e.g. WETH |
amount_ | uint256 | expected amount to pay for the job - must be greater than 0 |
maxTime_ | uint32 | maximum expected time (in sec) to deliver the job - must be greater than 0 |
deliveryMethod_ | string | preferred method of delivery (e.g. "IPFS", "Courier") |
arbitrator_ | address | address 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
Name | Type | Description |
---|---|---|
jobId_ | uint256 | id of the job |
signature_ | bytes | worker'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
Name | Type | Description |
---|---|---|
jobId_ | uint256 | ID of the job |
worker_ | address | An address of the worker selected for the job |
deliverResult
function deliverResult(uint256 jobId_, bytes32 resultHash_) public
Information about the job delivery
Parameters
Name | Type | Description |
---|---|---|
jobId_ | uint256 | Id of the job |
resultHash_ | bytes32 | e.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
Name | Type | Description |
---|---|---|
jobId_ | uint256 | |
reviewRating_ | uint8 | 1-5 (tbd) score of the worker. Set to 0 for no review |
reviewText_ | string | Optional 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
Name | Type | Description |
---|---|---|
jobId_ | uint256 | |
sessionKey_ | bytes | Encrypted session key for the arbitrator to decrypt owner's and worker's messages |
content_ | bytes | Encrypted 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
Name | Type | Description |
---|---|---|
jobId_ | uint256 | |
buyerShare_ | uint16 | how much of the payment should be refunded back to the buyer (in BPS) |
workerShare_ | uint16 | how much of the payment should be released to the worker (in BPS) |
reasonHash_ | bytes32 | reason 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)