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: upload the files #29

Open
wants to merge 46 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
6063546
feat: upload the files
siftal Jun 27, 2023
e93be66
fix: fix an issue
siftal Jun 28, 2023
12810e6
fix: remove an extra check
siftal Jun 28, 2023
4887e77
feat: refactor lockToBondedToken to restrict usage to NFT stakers
siftal Jun 28, 2023
26d3e41
feat: refactor mergeBondedTokens to restrict usage to NFT stakers
siftal Jun 28, 2023
4d3403a
feat: remove tier mapping and add tier field to the Node struct
siftal Jun 30, 2023
350da1c
feat: change tier type from uint64 to uint8
siftal Jul 4, 2023
0a0db3f
feat: remove unnecessary getTier function
siftal Jul 4, 2023
7c4920a
fix: fix an issue
siftal Jul 4, 2023
d14feb9
feat: remove unnecessary check
siftal Jul 4, 2023
518dd50
fix: fix an issue
siftal Jul 4, 2023
eacd683
feat: change minStakeAmountPerNode to minStakeAmount
siftal Jul 5, 2023
ad192c9
feat: add setMuonNodeTire function
siftal Jul 5, 2023
01ddb15
feat: remove unnecessary check
siftal Jul 5, 2023
7e64a40
feat: set balance to zero on node exit
siftal Jul 8, 2023
2abbcee
feat: calculate not paid rewards and redistribute them in the next di…
siftal Jul 8, 2023
585f9af
style: format the code
siftal Jul 8, 2023
c62cd70
feat: add getInfo function
siftal Jul 8, 2023
5c60340
test: update tests
siftal Jul 12, 2023
ee75a25
feat: add a new getEditedNodes function
siftal Jul 17, 2023
c5c1506
feat: let DAO_ROLE to deactivate a node
siftal Jul 17, 2023
edcfd0b
feat: check the balance of the node before withdrawing the stake
siftal Jul 17, 2023
46e3368
fix: add nodes' roles
siftal Jul 18, 2023
4e7b630
feat: get response length as a parameter
siftal Jul 18, 2023
c46dd01
fix: fix an issue
siftal Jul 18, 2023
e04c7da
feat: to improve performance break the loop instead of checking the c…
siftal Jul 18, 2023
27e6e6b
feat: make the nodesList size dynamic
siftal Jul 18, 2023
012bd68
test: update tests
siftal Jul 18, 2023
2cf81c3
feat: ables DAO to pause/unpause specific functions
siftal Jul 22, 2023
3420da0
test: update tests
siftal Jul 22, 2023
c1267aa
feat: use IERC20Upgradeable instead of IERC20
siftal Jul 22, 2023
245d8a0
fix: remove an extra import
siftal Jul 22, 2023
c1bbf8c
feat: add constant for reward period
siftal Jul 22, 2023
6797572
feat: check the NFT is received
siftal Jul 22, 2023
3b3dbdd
feat: write state variables before the call
siftal Jul 22, 2023
ac0b9db
feat: add onERC721Received function
siftal Jul 23, 2023
7e3bcc7
feat: check the node exists before setting the tier
siftal Jul 23, 2023
11531bf
feat: check the node exists before setting the tier
siftal Jul 23, 2023
b1361a8
feat: update messages
siftal Jul 23, 2023
ea5925a
style: clean the code
siftal Jul 23, 2023
74de8f4
test: update tests
siftal Jul 23, 2023
5e59c8a
feat: combine lockStake and unlockStake
siftal Jul 23, 2023
12c7c18
feat: use safeTransferFrom instead of transferFrom
siftal Jul 23, 2023
544b829
feat: combine pauseFunction and unpauseFunction
siftal Jul 25, 2023
fce9c5e
fix: fix a typo
siftal Aug 14, 2023
64e6044
fix: fix a typo
siftal Aug 14, 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
419 changes: 419 additions & 0 deletions contracts/MuonNodeManager.sol

Large diffs are not rendered by default.

680 changes: 680 additions & 0 deletions contracts/MuonNodeStaking.sol

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions contracts/interfaces/IBondedToken.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IBondedToken {
function lock(
uint256 tokenId,
address[] memory tokens,
uint256[] memory amounts
) external;

function merge(uint256 tokenIdA, uint256 tokenIdB) external;

function getLockedOf(uint256 tokenId, address[] memory tokens)
external
view
returns (uint256[] memory amounts);

function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;

function approve(address to, uint256 tokenId) external;

function ownerOf(uint256 tokenId) external view returns (address owner);
}
34 changes: 34 additions & 0 deletions contracts/interfaces/IMuonNodeManager.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

interface IMuonNodeManager {
struct Node {
uint64 id; // incremental ID
address nodeAddress; // will be used on the node
address stakerAddress;
string peerId; // p2p peer ID
bool active;
uint8 tier;
uint64[] roles;
uint256 startTime;
uint256 endTime;
uint256 lastEditTime;
}

function addNode(
address _nodeAddress,
address _stakerAddress,
string calldata _peerId,
bool _active
) external;

function deactiveNode(uint64 nodeId) external;

function stakerAddressInfo(address _addr)
external
view
returns (Node memory node);

function setTier(uint64 nodeId, uint8 tier) external;

}
12 changes: 12 additions & 0 deletions contracts/mock/PIONlpTest.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract PIONlpTest is ERC20 {
constructor() ERC20("PioneerLp", "PIONlp") {}

function mint(address to, uint256 amount) public {
_mint(to, amount);
}
}
10 changes: 10 additions & 0 deletions contracts/mock/PIONtest.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import "../Token.sol";

contract PIONtest is Token {
function initialize() public initializer {
Token._initialize("PioneerNetwork", "PION");
}
}
38 changes: 38 additions & 0 deletions contracts/utils/MuonClientBase.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import "./SchnorrSECP256K1Verifier.sol";

contract MuonClientBase is SchnorrSECP256K1Verifier{

struct SchnorrSign {
uint256 signature;
address owner;
address nonce;
}

struct PublicKey {
uint256 x;
uint8 parity;
}

event MuonTX(bytes reqId, PublicKey pubKey);

uint256 public muonAppId;
PublicKey public muonPublicKey;

function muonVerify(
bytes calldata reqId,
uint256 hash,
SchnorrSign memory signature,
PublicKey memory pubKey
) public returns (bool) {
if(!verifySignature(pubKey.x, pubKey.parity,
signature.signature,
hash, signature.nonce)){
return false;
}
emit MuonTX(reqId, pubKey);
return true;
}
}
128 changes: 128 additions & 0 deletions contracts/utils/SchnorrSECP256K1Verifier.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

contract SchnorrSECP256K1Verifier {
// See https://en.bitcoin.it/wiki/Secp256k1 for this constant.
uint256 constant public Q = // Group order of secp256k1
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141;
uint256 constant public HALF_Q = (Q >> 1) + 1;

/** **************************************************************************
@notice verifySignature returns true iff passed a valid Schnorr signature.
@dev See https://en.wikipedia.org/wiki/Schnorr_signature for reference.
@dev In what follows, let d be your secret key, PK be your public key,
PKx be the x ordinate of your public key, and PKyp be the parity bit for
the y ordinate (i.e., 0 if PKy is even, 1 if odd.)
**************************************************************************
@dev TO CREATE A VALID SIGNATURE FOR THIS METHOD
@dev First PKx must be less than HALF_Q. Then follow these instructions
(see evm/test/schnorr_test.js, for an example of carrying them out):
@dev 1. Hash the target message to a uint256, called msgHash here, using
keccak256
@dev 2. Pick k uniformly and cryptographically securely randomly from
{0,...,Q-1}. It is critical that k remains confidential, as your
private key can be reconstructed from k and the signature.
@dev 3. Compute k*g in the secp256k1 group, where g is the group
generator. (This is the same as computing the public key from the
secret key k. But it's OK if k*g's x ordinate is greater than
HALF_Q.)
@dev 4. Compute the ethereum address for k*g. This is the lower 160 bits
of the keccak hash of the concatenated affine coordinates of k*g,
as 32-byte big-endians. (For instance, you could pass k to
ethereumjs-utils's privateToAddress to compute this, though that
should be strictly a development convenience, not for handling
live secrets, unless you've locked your javascript environment
down very carefully.) Call this address
nonceTimesGeneratorAddress.
@dev 5. Compute e=uint256(keccak256(PKx as a 32-byte big-endian
‖ PKyp as a single byte
‖ msgHash
‖ nonceTimesGeneratorAddress))
This value e is called "msgChallenge" in verifySignature's source
code below. Here "‖" means concatenation of the listed byte
arrays.
@dev 6. Let x be your secret key. Compute s = (k - d * e) % Q. Add Q to
it, if it's negative. This is your signature. (d is your secret
key.)
**************************************************************************
@dev TO VERIFY A SIGNATURE
@dev Given a signature (s, e) of msgHash, constructed as above, compute
S=e*PK+s*generator in the secp256k1 group law, and then the ethereum
address of S, as described in step 4. Call that
nonceTimesGeneratorAddress. Then call the verifySignature method as:
@dev verifySignature(PKx, PKyp, s, msgHash,
nonceTimesGeneratorAddress)
**************************************************************************
@dev This signging scheme deviates slightly from the classical Schnorr
signature, in that the address of k*g is used in place of k*g itself,
both when calculating e and when verifying sum S as described in the
verification paragraph above. This reduces the difficulty of
brute-forcing a signature by trying random secp256k1 points in place of
k*g in the signature verification process from 256 bits to 160 bits.
However, the difficulty of cracking the public key using "baby-step,
giant-step" is only 128 bits, so this weakening constitutes no compromise
in the security of the signatures or the key.
@dev The constraint signingPubKeyX < HALF_Q comes from Eq. (281), p. 24
of Yellow Paper version 78d7b9a. ecrecover only accepts "s" inputs less
than HALF_Q, to protect against a signature- malleability vulnerability in
ECDSA. Schnorr does not have this vulnerability, but we must account for
ecrecover's defense anyway. And since we are abusing ecrecover by putting
signingPubKeyX in ecrecover's "s" argument the constraint applies to
signingPubKeyX, even though it represents a value in the base field, and
has no natural relationship to the order of the curve's cyclic group.
**************************************************************************
@param signingPubKeyX is the x ordinate of the public key. This must be
less than HALF_Q.
@param pubKeyYParity is 0 if the y ordinate of the public key is even, 1
if it's odd.
@param signature is the actual signature, described as s in the above
instructions.
@param msgHash is a 256-bit hash of the message being signed.
@param nonceTimesGeneratorAddress is the ethereum address of k*g in the
above instructions
**************************************************************************
@return True if passed a valid signature, false otherwise. */
function verifySignature(
uint256 signingPubKeyX,
uint8 pubKeyYParity,
uint256 signature,
uint256 msgHash,
address nonceTimesGeneratorAddress) public pure returns (bool) {
require(signingPubKeyX < HALF_Q, "Public-key x >= HALF_Q");
// Avoid signature malleability from multiple representations for ℤ/Qℤ elts
require(signature < Q, "signature must be reduced modulo Q");

// Forbid trivial inputs, to avoid ecrecover edge cases. The main thing to
// avoid is something which causes ecrecover to return 0x0: then trivial
// signatures could be constructed with the nonceTimesGeneratorAddress input
// set to 0x0.
//
require(nonceTimesGeneratorAddress != address(0) && signingPubKeyX > 0 &&
signature > 0 && msgHash > 0, "no zero inputs allowed");

uint256 msgChallenge = // "e"
uint256(keccak256(abi.encodePacked(nonceTimesGeneratorAddress, msgHash)));

// Verify msgChallenge * signingPubKey + signature * generator ==
// nonce * generator
//
// https://ethresear.ch/t/you-can-kinda-abuse-ecrecover-to-do-ecmul-in-secp256k1-today/2384/9
// The point corresponding to the address returned by
// ecrecover(-s*r,v,r,e*r) is (r⁻¹ mod Q)*(e*r*R-(-s)*r*g)=e*R+s*g, where R
// is the (v,r) point. See https://crypto.stackexchange.com/a/18106
//
address recoveredAddress = ecrecover(
bytes32(Q - mulmod(signingPubKeyX, signature, Q)),
// https://ethereum.github.io/yellowpaper/paper.pdf p. 24, "The
// value 27 represents an even y value and 28 represents an odd
// y value."
(pubKeyYParity == 0) ? 27 : 28,
bytes32(signingPubKeyX),
bytes32(mulmod(msgChallenge, signingPubKeyX, Q)));
return nonceTimesGeneratorAddress == recoveredAddress;
}

function validatePubKey (uint256 signingPubKeyX) public pure {
require(signingPubKeyX < HALF_Q, "Public-key x >= HALF_Q");
}
}
Loading