Skip to content

Commit 5569b12

Browse files
committed
Initial commit
0 parents  commit 5569b12

23 files changed

+25664
-0
lines changed

.editorconfig

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# EditorConfig http://EditorConfig.org
2+
3+
# top-most EditorConfig file
4+
root = true
5+
6+
# All files
7+
[*]
8+
charset = utf-8
9+
end_of_line = lf
10+
indent_size = 2
11+
indent_style = space
12+
insert_final_newline = true
13+
trim_trailing_whitespace = true
14+
15+
[*.sol]
16+
indent_size = 4
17+
18+
[*.md]
19+
trim_trailing_whitespace = false

.eslintignore

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# folders
2+
artifacts/
3+
build/
4+
cache/
5+
coverage/
6+
dist/
7+
lib/
8+
node_modules/
9+
typechain/
10+
11+
# files
12+
.solcover.js
13+
coverage.json

.eslintrc.js

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module.exports = {
2+
env: {
3+
browser: true,
4+
es2021: true,
5+
node: true,
6+
},
7+
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
8+
overrides: [],
9+
parser: "@typescript-eslint/parser",
10+
parserOptions: {
11+
ecmaVersion: "latest",
12+
sourceType: "module",
13+
},
14+
plugins: ["@typescript-eslint"],
15+
rules: {},
16+
};

.gitignore

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
node_modules
2+
.env
3+
coverage
4+
coverage.json
5+
typechain
6+
typechain-types
7+
8+
#Hardhat files
9+
cache
10+
artifacts

.prettierignore

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# folders
2+
artifacts/
3+
build/
4+
cache/
5+
coverage/
6+
dist/
7+
lib/
8+
node_modules/
9+
typechain/
10+
11+
# files
12+
coverage.json

.prettierrc

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"arrowParens": "avoid",
3+
"bracketSpacing": true,
4+
"endOfLine":"auto",
5+
"printWidth": 80,
6+
"singleQuote": false,
7+
"tabWidth": 2,
8+
"trailingComma": "all",
9+
"overrides": [
10+
{
11+
"files": "*.sol",
12+
"options": {
13+
"tabWidth": 4,
14+
"printWidth": 120
15+
}
16+
},
17+
{
18+
"files": "*.md",
19+
"options": {
20+
"bracketSpacing": false
21+
}
22+
}
23+
]
24+
}

.solhint.json

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"extends": "solhint:recommended",
3+
"plugins": ["prettier"],
4+
"rules": {
5+
"code-complexity": ["error", 7],
6+
"compiler-version": ["error", "^0.8.0"],
7+
"const-name-snakecase": "off",
8+
"constructor-syntax": "error",
9+
"func-visibility": ["error", { "ignoreConstructors": true }],
10+
"max-line-length": ["error", 120],
11+
"not-rely-on-time": "off",
12+
"prettier/prettier": [
13+
"error",
14+
{
15+
"endOfLine": "auto"
16+
}
17+
],
18+
"reason-string": ["warn", { "maxLength": 64 }]
19+
}
20+
}

.solhintignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# folders
2+
.yarn/
3+
build/
4+
dist/
5+
node_modules/

README.md

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Escrow System
2+
3+
## About
4+
It’s functionality is similar to normal freelancing platforms.
5+
On a freelancing platform, a client can create a project. And hire several developers on the project. After discussion with a developer, the client creates a milestone and deposit funds to escrow. And once the developer delivers work, they release the fund in escrow to the developer. And a client can file a dispute in a certain period.
6+
We’re going to implement this system using a smart contract.
7+
On our project, let’s define some words: `originator` (same as client) and `participant`(same as developer)
8+
We use cryptocurrency, and once the fund is transferred to a participant, we can’t dispute it. So funds will be transferred to a participant through a vesting contract. Before it’s being released, clients can file a dispute.
9+
10+
## Core contract
11+
EscrowFactory: Originators can create escrows here
12+
13+
Escrow: Originators can create milestones and manage funds. Participants will use this contract to get paid.
14+
15+
Locker: If originators release funds, fund is transferred to vesting contract and originators can claim after some time.
16+
17+
## Project Specs
18+
19+
### EscrowFactory
20+
- This contract has a variable named `createFee`, `feeRecipient` and `feePercent`.
21+
When an originator create an escrow, they should pay a certain amount of ETH. It will be transferred to `feeRecipient`.
22+
When originator releases milestone fund, some percent will be transferred to `feeRecipient` address.
23+
- This contract has a function named `createEscrow`.
24+
It will receive `uri`(string) as a parameter and create an escrow contract. And uri is saved on `escrow` contract.
25+
The front-end also need to get a list of escrows owned by a certain wallet.
26+
The front-end also need to get a list of all available escrows.
27+
- It has operators registration. Operators can assets milestone dispute if originator and participants don’t agree each other.
28+
- It has locker(address) and lockDuration(uint256).
29+
Locker is the address of locker contract. LockDuration is the duration of fund lock when the originator releases the fund.
30+
- This contract has a function named `destroy`. This will be called from escrow contract to remove `escrow` from `factory`.
31+
32+
_You can define and use other necessary variables and functions._
33+
34+
### Escrow
35+
- Flow of a `milestone`.
36+
- Originator create a milestone
37+
- Originator can create a milestone info before participant agrees
38+
- Participant can agree with a milestone
39+
- Originator deposits funds to agreed milestone
40+
- Originator can released fund, or if they don’t release it, participant can request fund after dueDate of the milestone
41+
- Originator can file a dispute for released milestones (only when milestone fund is released, but it’s in Locker contract and it’s locked. => block.timestamp – released timestamp < lockDuration)
42+
If milestone fund in Locker is available to claim and participant doesn’t claim yet, originator can’t file a dispute.
43+
- Participant can accept dispute, and then fund in Locker contract is immediately sent back to originator.
44+
- Originator can cancel a dispute.
45+
- Also, operator can accept/cancel a dispute if participant and originator don’t agree each other.
46+
- It will have `overview` info. (count of created milestones, deposited milestones, released milestones, disputed milestones)
47+
- `updateMeta` function is to update metadata of an escrow
48+
- `createMilestone(address token, address participant, uint256 amount, uint256 timestamp, string memory meta)`: timestamp is unix timestamp of dueDate. Meta is just a string value of milestone description. And only called by originator
49+
- `updateMilestone(uint256 _mId, token, participant, amount, timestamp, meta)`: It can be called before milestone is agreed by participant. And only called by originator
50+
- `agreeMilestone(mId)`: only called by participant. It’s to accept a certain milestone.
51+
- `depositMilestone(mId)`: only called by originator, and deposit fund of milestone to this contract
52+
- `requestMilestone(mId)`: only called by participant when it’s not released and it’s over dueDate
53+
- `releaseMilestone(mId)`: only called by originator and release fund. Fund is transferred to Lock contract
54+
- `createDispute(mId)`: only called by originator.
55+
- `resolveDispute(mId)`: only called by participant or operator.
56+
- `cancelDispute(mId)`: only called by originator or operator.
57+
- `destroy()`: only called by originator, when all milestones are released. It will call factory.destroy() and destroy the current escrow contract
58+
59+
_You can define and use other necessary variables and functions._
60+
61+
### Locker
62+
- `Create(_token, amount, beneficiary, mId, unlockTimestamp)`: Called by escrow contracts only.
63+
- `Release(lockId)`: Release fund to `beneficiary` address of `lockId` (if lockDuration is passed)
64+
65+
_You can define and use other necessary variables and functions._
66+
67+
## Example
68+
### About dispute flow:
69+
LockDuration is one week.
70+
Originator released milestoneA to Participant on 1th.
71+
Originator can file a dispute for milestoneA before 8th.
72+
After 8th, participant can release the fund.
73+
After 8th, originator can’t file a dispute even if participant doesn’t release it.
74+
75+
Let’s assume that originator filed a dispute on 6th.
76+
Then participant can’t release fund on 8th or 9 th…
77+
If that dispute is cancelled on 7th, participant can release after 8th.
78+
79+
## Reference:
80+
When deploying a new contract, `don’t use new`. In that case, code size of factory contract is bigger, and it’s a bad practice.
81+
Use [Clones.clone](https://docs.openzeppelin.com/contracts/4.x/api/proxy#Clones) and [factory](https://github.com/pancakeswap/pancake-smart-contracts/blob/master/projects/farms-pools/contracts/SmartChefFactory.sol) and [initialize](https://github.com/pancakeswap/pancake-smart-contracts/blob/master/projects/farms-pools/contracts/SmartChefInitializable.sol) model.
82+
When destorying a contract, use [selfdestruct](https://solidity-by-example.org/hacks/self-destruct/)
83+
84+
## Command
85+
This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, and a script that deploys that contract.
86+
87+
Try running some of the following tasks:
88+
89+
```shell
90+
npx hardhat help
91+
npx hardhat test
92+
GAS_REPORT=true npx hardhat test
93+
npx hardhat node
94+
npx hardhat run scripts/deploy.ts
95+
```

0 commit comments

Comments
 (0)