Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: initial implementation #1

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
dc326a9
feat(global): adds first stuff
allemanfredi Nov 8, 2022
4253c6f
refactor(contracts): rn fx
allemanfredi Nov 8, 2022
86791cf
chore(global): rm not used dependencies
allemanfredi Nov 8, 2022
5290bd2
chore(global): rn project name
allemanfredi Nov 8, 2022
2dffa00
chore(global): rm useless stuff
allemanfredi Nov 8, 2022
3ccfef4
feat(test): adds one test
allemanfredi Nov 8, 2022
3049cc2
refactor(scripts): adds token value within deploy-agreement
allemanfredi Nov 9, 2022
1fb3cb3
feat(contracts & test): adds acceptAndClaimOwner
allemanfredi Nov 9, 2022
4634c94
chore(global): fixes dependencies
allemanfredi Nov 9, 2022
ba356ec
refactor(contracts & test): adds some value checks and improves tests
allemanfredi Nov 9, 2022
ede82a2
refactor(test): changes IPFS_MULTIHASH test value
allemanfredi Nov 9, 2022
f8f3603
chore(global): change file dir
allemanfredi Nov 9, 2022
7967727
refactor(global): adds last changes
allemanfredi Nov 9, 2022
28c08ac
feat(contracts & test): adds Agreement2
allemanfredi Nov 10, 2022
0c06cc4
feat(contracts & test): adds acceptAndClaimManyOwner and changes acce…
allemanfredi Nov 10, 2022
53d2979
feat(test): adds more tests
allemanfredi Nov 10, 2022
91516a2
feat(scripts): adds accept-and-claim-many-owner
allemanfredi Nov 10, 2022
293fa09
feat(scripts): adds 2 helper scripts
allemanfredi Nov 10, 2022
b723c32
refactor(scripts & test): formats
allemanfredi Oct 5, 2023
439629d
refactor(contracts): refactors Agreement2
allemanfredi Oct 6, 2023
a1524ea
feat(tasks): starts adding Agreement2 tasks
allemanfredi Oct 6, 2023
cfcab43
refactor(global): rm scripts and adds tasks
allemanfredi Oct 6, 2023
75a3fcf
refactor(tasks): casts chunkSize to be a number, rm types and adds fi…
allemanfredi Oct 10, 2023
da1293a
feat(tasks): adds wait within step2:set-claim-for-many
allemanfredi Oct 11, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
module.exports = {
parserOptions: {
ecmaVersion: 2018,
ecmaFeatures: {
impliedStrict: true,
},
},
extends: ['eslint:recommended', 'standard'],
env: {
es6: true,
mocha: true,
node: true,
},
// ADD ANY GLOBALS HERE!
globals: {
web3: false,
contract: false,
artifacts: false,
},
rules: {
'max-len': [
'error',
120,
2,
{
ignoreUrls: true,
ignoreComments: false,
ignoreRegExpLiterals: true,
ignoreStrings: false,
ignoreTemplateLiterals: false,
},
],
quotes: [2, 'single', { avoidEscape: true }],
'prefer-promise-reject-errors': 1,
'standard/computed-property-even-spacing': 0,
'no-mixed-operators': 0,
'comma-dangle': 0,
camelcase: 0, // Due to info getter in eosjs
'no-unused-expressions': 1,
'no-template-curly-in-string': 2,
'no-extra-parens': [1, 'all'],
'no-misleading-character-class': 1,
'no-prototype-builtins': 1,
'no-async-promise-executor': 1,
'no-await-in-loop': 0, // should probably be on for perf dependent application
'require-atomic-updates': 1,
// best practices
'accessor-pairs': 1,
'array-callback-return': 0, // this best practice calls out the use of map over forEach
'class-methods-use-this': 1,
curly: [1, 'multi-or-nest', 'consistent'],
'dot-location': [2, 'property'],
'no-empty-function': 1,
'no-eval': 2,
'no-extend-native': 1,
'no-extra-bind': 1,
'no-implicit-coercion': 1,
'no-implicit-globals': 2,
'no-implied-eval': 2,
'no-lone-blocks': 1,
'no-loop-func': 1,
'no-magic-numbers': 0, // could be useful?
'no-new': 1,
'no-new-func': 2,
'no-new-wrappers': 1,
'no-param-reassign': 2,
'no-redeclare': [2, { builtinGlobals: true }],
'no-shadow': [
2,
{
builtinGlobals: true,
allow: [
'done',
'resolve',
'reject',
'cb', // x could potentially be added
],
},
],
'no-return-await': 1,
'no-script-url': 1,
'no-self-compare': 1,
'no-sequences': 1,
'no-throw-literal': 2,
'no-unmodified-loop-condition': 1,
'no-useless-call': 1,
'no-useless-catch': 1,
'no-useless-concat': 2,
'no-useless-escape': 2,
'no-useless-return': 0,
'no-console': [
'error',
{
allow: ['warn', 'error', 'info'],
},
],
'no-warning-comments': [
1,
{
terms: ['fixme', 'todo'],
location: 'anywhere', // useful to highlight comments that need addressing
},
],
'require-await': 1,
'vars-on-top': 2,
'wrap-iife': [2, 'inside'],
// strict mode
strict: [2, 'safe'],
// variables
'no-use-before-define': [
2,
{
variables: true,
functions: true,
classes: true,
},
],
// node
'handle-callback-err': 1,
'no-buffer-constructor': 2,
'no-mixed-requires': 2,
'no-new-require': 0,
'no-path-concat': 1,
'no-sync': 1,
// stylistic (leaving up to standard)

// ECMAScript 6 (tbd)
},
}
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
node_modules
.DS_Store
.openzeppelin
.env
*.sw*

#Hardhat files
cache
artifacts

hidden_addresses*.csv
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v16
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
artifacts
cache
20 changes: 20 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"tabWidth": 2,
"semi": false,
"singleQuote": true,
"bracketSpacing": true,
"printWidth": 120,
"overrides": [
{
"files": "*.sol",
"options": {
"printWidth": 150,
"tabWidth": 4,
"useTabs": false,
"singleQuote": false,
"bracketSpacing": false,
"explicitTypes": "always"
}
}
]
}
14 changes: 14 additions & 0 deletions .solhint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"rules": {
"no-unused-vars": "error",
"const-name-snakecase": "error",
"contract-name-camelcase": "error",
"event-name-camelcase": "error",
"func-name-mixedcase": "error",
"func-param-name-mixedcase": "error",
"modifier-name-mixedcase": "error",
"private-vars-leading-underscore": "error",
"var-name-mixedcase": "error",
"imports-on-top": "error"
}
}
1 change: 1 addition & 0 deletions .soliumignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
51 changes: 50 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,50 @@
# pgala-compensation-plan-contracts
# pgala-recovery-plan-contracts

pGALA recovery plan contracts

 

***

 

## :guardsman: Smart Contract Tests

```
❍ npm install
```

```
❍ npm run test
```


 

***

 

## :white_check_mark: How to publish & verify

Create an __.env__ file with the following fields:

```
BSC_MAINNET_NODE=
BSCSCAN_API_KEY=
BSC_MAINNET_PRIVATE_KEY=
```


### publish


```
❍ npx hardhat run --network mainnet scripts/deploy-script.js
```

### verify

```
❍ npx hardhat verify --network mainnet DEPLOYED_CONTRACT_ADDRESS "Constructor argument 1"
```
115 changes: 115 additions & 0 deletions contracts/Agreement.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import {IERC777RecipientUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC777/IERC777RecipientUpgradeable.sol";
import {IERC1820Registry} from "@openzeppelin/contracts/interfaces/IERC1820Registry.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Errors} from "./libraries/Errors.sol";

contract Agreement is Initializable, OwnableUpgradeable, IERC777RecipientUpgradeable {
mapping(address => uint256) _toClaim;
mapping(address => uint256) _claimed;

string public ipfsMultihash;
address public token;

event AcceptedAndClaimed(address indexed owner, string ipfsMultihash, uint256 amount);
event IpfsMultihashChanged(string ipfsMultihash);
event ClaimForSet(address owner, uint256 amount);

function initialize(string calldata _ipfsMultihash, address _token) external initializer {
IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24).setInterfaceImplementer(
address(this),
keccak256("ERC777TokensRecipient"),
address(this)
);
ipfsMultihash = _ipfsMultihash;
token = _token;
__Ownable_init();
}

function tokensReceived(
address /*_operator*/,
address _from,
address /*_to*/,
uint256 /*_amount,*/,
bytes calldata /* _userData, */,
bytes calldata /*_operatorData */
) external view override {
if (_msgSender() == token && _from != owner()) {
revert Errors.OnlyOwnerCanDepositToken();
}
}

function changeIpfsMultihash(string calldata _ipfsMultihash) external onlyOwner {
ipfsMultihash = _ipfsMultihash;
allemanfredi marked this conversation as resolved.
Show resolved Hide resolved
emit IpfsMultihashChanged(_ipfsMultihash);
}

function acceptAndClaim(string calldata _ipfsMultihash) external {
if (keccak256(abi.encodePacked((_ipfsMultihash))) != keccak256(abi.encodePacked((ipfsMultihash)))) {
revert Errors.InvalidIpfsMultiHash();
}

address msgSender = _msgSender();
uint256 amountToClaim = getClaimableAmountFor(msgSender);

if (amountToClaim == 0) {
revert Errors.NothingToClaim();
}

_acceptAndClaimFor(msgSender, msgSender, amountToClaim, _ipfsMultihash);
}

function acceptAndClaimManyOwner(address[] calldata _owners) external onlyOwner {
address msgSender = _msgSender();
for (uint256 i = 0; i < _owners.length; i++) {
uint256 amountToClaim = getClaimableAmountFor(_owners[i]);
_acceptAndClaimFor(_owners[i], msgSender, amountToClaim, "");
}
}

function acceptAndClaimOwner(address _owner) external onlyOwner {
uint256 amountToClaim = getClaimableAmountFor(_owner);
_acceptAndClaimFor(_owner, _msgSender(), amountToClaim, "");
}

function setClaimForMany(address[] calldata _owners, uint256[] calldata _amounts) public onlyOwner {
if (_owners.length != _amounts.length) {
revert Errors.InvalidLength();
}

for (uint256 i = 0; i < _owners.length; i++) {
allemanfredi marked this conversation as resolved.
Show resolved Hide resolved
setClaimFor(_owners[i], _amounts[i]);
}
}

function setClaimFor(address _owner, uint256 _amount) public onlyOwner {
if (_amount == 0) {
revert Errors.InvalidAmount();
}

_toClaim[_owner] = _amount;
gskapka marked this conversation as resolved.
Show resolved Hide resolved
emit ClaimForSet(_owner, _amount);
}

function getClaimableAmountFor(address _owner) public view returns (uint256) {
return _toClaim[_owner] - _claimed[_owner];
gskapka marked this conversation as resolved.
Show resolved Hide resolved
}

function getClaimedAmountFor(address _owner) public view returns (uint256) {
return _claimed[_owner];
}

function emergencyWithdraw() external onlyOwner {
IERC20(token).transfer(_msgSender(), IERC20(token).balanceOf(address(this)));
}

function _acceptAndClaimFor(address _owner, address _receiver, uint256 _amount, string memory _ipfsMultihash) internal {
_claimed[_owner] += _amount;
gskapka marked this conversation as resolved.
Show resolved Hide resolved
IERC20(token).transfer(_receiver, _amount);
emit AcceptedAndClaimed(_owner, _ipfsMultihash, _amount);
}
}
Loading