Skip to content

Commit

Permalink
Merge staking feature branch into develop (#19)
Browse files Browse the repository at this point in the history
Add support for staking contract (#12)

* :WIP: Implement handler for staking lockAmount function

* :WIP: Revert and implement handler for reward createPosition function

* 🌱 Add a new unit test for create position for reward contract

* 🐛 Fix implementation and generate snapshots

* Implement handler for fast unlock

* 🌱 Add a new unit test for the fast unlock method

* Fix handler for initFastUnlock

* Add handlers for claimRewards, pauseUnlocking and resumeUnlocking

* 🔨 Code refactoring

* 🐛 Fix CI

* 🌱 Update to support the increaseLockingAmount method

 - Also add a new unit test for that

* 🌱 Update to support the extendDuration method

 - Also add a new unit test for that

* Update Readme

* 💅 Rename a method name

* 🌱 Update to support the deletePositions method

 - Add a new unit test for that
 - Generate snapshots

* 💅 Rename some consts

* 🌱 Update to support the addUnusedRewards method

 - Add a new unit test for that
 - Generate snapshots

* 🌱 Update to support fundStakingRewards method

 - Add a new unit test for that
 - Generate snapshots

* 👌 Applied suggestions

* 🐛 Fix the Makefile

---------

Co-authored-by: hatef <[email protected]>
  • Loading branch information
nagdahimanshu and hrmhatef authored May 29, 2024
1 parent 43ae173 commit 4976964
Show file tree
Hide file tree
Showing 341 changed files with 1,844 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ ColumnLimit: 100
PointerAlignment: Right
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: true
AllowAllParametersOfDeclarationOnNextLine: false
SortIncludes: false
SpaceAfterCStyleCast: true
AllowShortCaseLabelsOnASingleLine: false
Expand All @@ -18,3 +17,4 @@ AllowShortFunctionsOnASingleLine: None
BinPackArguments: false
BinPackParameters: false
---

4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ ifeq ($(TARGET_NAME),TARGET_STAX)
DEFINES += ICONBITMAP=C_stax_$(NORMAL_NAME)_64px_bitmap
endif

CURVE_APP_LOAD_PARAMS = ed25519
CURVE_APP_LOAD_PARAMS = secp256k1
PATH_APP_LOAD_PARAMS = "44'/134'"

VARIANT_PARAM = COIN
VARIANT_VALUES = LSK
VARIANT_VALUES = lisk

DISABLE_STANDARD_APP_FILES = 1
DISABLE_STANDARD_SNPRINTF = 1
Expand Down
25 changes: 18 additions & 7 deletions PLUGIN_SPECIFICATION.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
# Technical Specification

## Smart Contracts

Smart contracts covered by this plugin are:

| Network | Version | Smart Contract | Address |
| ---- | --- | ---- | --- |
| Lisk Sepolia Testnet | - | TokenClaim | `0x5c3a68B5C635Ce0DA7648C30A1B83A61C376bd87` |
| Network | Version | Smart Contract | Address |
| -------------------- | ------- | -------------- | -------------------------------------------- |
| Lisk Sepolia Testnet | - | TokenClaim | `0x3D4190b08E3E30183f5AdE3A116f2534Ee3a4f94` |
| Lisk Sepolia Testnet | - | Reward | `0xFd322B4724C497E59D48fff8f79c16b4D48837f5` |
| Lisk Mainnet | - | TokenClaim | `0xD7BE2Fd98BfD64c1dfCf6c013fC593eF09219994` |
| Lisk Mainnet | - | Reward | `0xD35ca9577a9DADa7624a35EC10C2F55031f0Ab1f` |

## Functions

Following functions are covered by this plugins:

|Contract | Function | Selector | Displayed Parameters |
| --- | --- | --- | --- |
|ERC1967Proxy | claimRegularAccount | `0xf6de242d`| <table> <tbody> <tr><td><code>uint256 claimAmount</code></td></tr> <tr><td><code>bytes senderPublicKey</code></td></tr> <tr><td><code>address recipientAddress</code></td></tr> </tbody> </table> |
|ERC1967Proxy | claimMultisigAccount | `0x2f559f68`| <table> <tbody> <tr><td><code>uint256 claimAmount</code></td></tr> <tr><td><code>bytes senderAddress</code></td></tr> <tr><td><code>address recipientAddress</code></td></tr> </tbody> </table> |
| Contract | Function | Selector | Displayed Parameters |
| ---------- | ------------------------ | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| TokenClaim | claimRegularAccount | `0xf6de242d` | <table> <tbody> <tr><td><code>uint256 claimAmount</code></td></tr> <tr><td><code>bytes senderPublicKey</code></td></tr> <tr><td><code>address recipientAddress</code></td></tr> </tbody> </table> |
| TokenClaim | claimMultisigAccount | `0x2f559f68` | <table> <tbody> <tr><td><code>uint256 claimAmount</code></td></tr> <tr><td><code>bytes senderAddress</code></td></tr> <tr><td><code>address recipientAddress</code></td></tr> </tbody> </table> |
| Reward | createPosition | `0xd1aaef05` | <table> <tbody> <tr><td><code>uint256 lockAmount</code></td></tr> <tr><td><code>uint256 lockDuration</code></td></tr> </tbody> </table> |
| Reward | initiateFastUnlock | `0x864c8725` | <table> <tbody> <tr><td><code>uint256[] lockIDs</code></td></tr> </tbody> </table> |
| Reward | claimRewards | `0x5eac6239` | <table> <tbody> <tr><td><code>uint256[] lockIDs</code></td></tr> </tbody> </table> |
| Reward | pauseUnlocking | `0xfe042b5b` | <table> <tbody> <tr><td><code>uint256[] lockIDs</code></td></tr> </tbody> </table> |
| Reward | resumeUnlockingCountdown | `0x82d4ae58` | <table> <tbody> <tr><td><code>uint256[] lockIDs</code></td></tr> </tbody> </table> |
| Reward | increaseLockingAmount | `0xf94415ca` | <table> <tbody> <tr><td><code>(uint256 lockID, uint256 amountIncrease)[]</code></td></tr> </tbody> </table> |
| Reward | extendDuration | `0x2d412a71` | <table> <tbody> <tr><td><code>(uint256 lockID, uint256 durationExtension)[]</code></td></tr> </tbody> </table> |
16 changes: 16 additions & 0 deletions src/handle_finalize.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,24 @@ void handle_finalize(ethPluginFinalize_t *msg) {
switch (context->selectorIndex) {
case CLAIM_REGULAR_ACCOUNT:
case CLAIM_MULTI_SIGNATURE_ACCOUNT:
case REWARD_ADD_UNUSED_REWARDS:
case REWARD_FUND_STAKING_REWARDS:
msg->numScreens = 3;
break;
case REWARD_CREATE_POSITION:
msg->numScreens = 2;
break;
case REWARD_INIT_FAST_UNLOCK:
case REWARD_CLAIM_REWARDS:
case REWARD_PAUSE_UNLOCKING:
case REWARD_RESUME_UNLOCKING:
case REWARD_DELETE_POSITIONS:
msg->numScreens = context->lisk.body.reward.lock_ids_len;
break;
case REWARD_INC_LOCKING_AMOUNT:
case REWARD_EXTEND_DURATION:
msg->numScreens = context->lisk.body.rewardIncLockingAmount.len * 2;
break;
default:
msg->result = ETH_PLUGIN_RESULT_ERROR;
return;
Expand Down
14 changes: 14 additions & 0 deletions src/handle_init_contract.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,20 @@ void handle_init_contract(ethPluginInitContract_t *msg) {
case CLAIM_MULTI_SIGNATURE_ACCOUNT:
context->next_param = PROOF;
break;
case REWARD_CREATE_POSITION:
case REWARD_ADD_UNUSED_REWARDS:
case REWARD_FUND_STAKING_REWARDS:
context->next_param = AMOUNT;
break;
case REWARD_INIT_FAST_UNLOCK:
case REWARD_CLAIM_REWARDS:
case REWARD_PAUSE_UNLOCKING:
case REWARD_RESUME_UNLOCKING:
case REWARD_INC_LOCKING_AMOUNT:
case REWARD_EXTEND_DURATION:
case REWARD_DELETE_POSITIONS:
context->next_param = OFFSET;
break;
// Keep this
default:
PRINTF("Missing selectorIndex: %d\n", context->selectorIndex);
Expand Down
198 changes: 198 additions & 0 deletions src/handle_provide_parameter.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "plugin.h"

uint16_t counter = 0;

static void handle_claim_regular_account(ethPluginProvideParameter_t *msg, context_t *context) {
switch (context->next_param) {
case PROOF: // _proof
Expand All @@ -24,6 +26,9 @@ static void handle_claim_regular_account(ethPluginProvideParameter_t *msg, conte
context->next_param = ED25519_SIGNATURE;
break;
case ED25519_SIGNATURE: // _sig
context->next_param = UNEXPECTED_PARAMETER;
break;
case UNEXPECTED_PARAMETER:
break;
default:
PRINTF("Param not supported: %d\n", context->next_param);
Expand Down Expand Up @@ -59,6 +64,179 @@ static void handle_claim_multisig_account(ethPluginProvideParameter_t *msg, cont
context->next_param = ED25519_SIGNATURES;
break;
case ED25519_SIGNATURES: // _sigs
context->next_param = UNEXPECTED_PARAMETER;
break;
case UNEXPECTED_PARAMETER:
break;
default:
PRINTF("Param not supported: %d\n", context->next_param);
msg->result = ETH_PLUGIN_RESULT_ERROR;
break;
}
}

static void handle_reward_create_position(ethPluginProvideParameter_t *msg, context_t *context) {
switch (context->next_param) {
case AMOUNT: // amount
copy_parameter(context->lisk.body.rewardCreatePosition.lock_amount,
msg->parameter,
sizeof(context->lisk.body.rewardCreatePosition.lock_amount));
context->next_param = DURATION;
break;
case DURATION: // lockingDuration
copy_parameter(context->lisk.body.rewardCreatePosition.lock_duration,
msg->parameter,
sizeof(context->lisk.body.rewardCreatePosition.lock_duration));
context->next_param = UNEXPECTED_PARAMETER;
break;
case UNEXPECTED_PARAMETER:
break;
default:
PRINTF("Param not supported: %d\n", context->next_param);
msg->result = ETH_PLUGIN_RESULT_ERROR;
break;
}
}

static void handle_lock_ids_array(ethPluginProvideParameter_t *msg, context_t *context) {
switch (context->next_param) {
case OFFSET:
context->next_param = LOCK_IDS_LEN;
break;
case LOCK_IDS_LEN:
if (!U2BE_from_parameter(msg->parameter, &context->lisk.body.reward.lock_ids_len) ||
context->lisk.body.reward.lock_ids_len > 4 ||
context->lisk.body.reward.lock_ids_len == 0) {
msg->result = ETH_PLUGIN_RESULT_ERROR;
}

context->next_param = LOCK_ID;
break;
case LOCK_ID:
copy_parameter(context->lisk.body.reward.lock_id[counter].value,
msg->parameter,
INT256_LENGTH);
if (counter == context->lisk.body.reward.lock_ids_len - 1) {
counter = 0;
context->next_param = NONE;
} else {
counter++;
}
break;
case NONE:
break;
default:
PRINTF("Param not supported\n");
msg->result = ETH_PLUGIN_RESULT_ERROR;
break;
}
}

static void handle_increase_locking_amount(ethPluginProvideParameter_t *msg, context_t *context) {
switch (context->next_param) {
case OFFSET:
context->next_param = INCREASE_LEN;
break;
case INCREASE_LEN:
if (!U2BE_from_parameter(msg->parameter,
&context->lisk.body.rewardIncLockingAmount.len) ||
context->lisk.body.rewardIncLockingAmount.len > 2 ||
context->lisk.body.rewardIncLockingAmount.len == 0) {
msg->result = ETH_PLUGIN_RESULT_ERROR;
}

context->next_param = LOCK_ID;
break;
case LOCK_ID:
copy_parameter(context->lisk.body.rewardIncLockingAmount.lock_id[counter].value,
msg->parameter,
INT256_LENGTH);
context->next_param = AMOUNT;
break;
case AMOUNT:
copy_parameter(context->lisk.body.rewardIncLockingAmount.amount[counter].value,
msg->parameter,
INT256_LENGTH);
if (context->lisk.body.rewardIncLockingAmount.len > 1 &&
counter < context->lisk.body.rewardIncLockingAmount.len - 1) {
counter++;
context->next_param = LOCK_ID;
} else {
context->next_param = NONE;
}
break;
case NONE:
break;
default:
PRINTF("Param not supported\n");
msg->result = ETH_PLUGIN_RESULT_ERROR;
break;
}
}

static void handle_extend_duration(ethPluginProvideParameter_t *msg, context_t *context) {
switch (context->next_param) {
case OFFSET:
context->next_param = INCREASE_LEN;
break;
case INCREASE_LEN:
if (!U2BE_from_parameter(msg->parameter,
&context->lisk.body.rewardExtendDuration.len) ||
context->lisk.body.rewardExtendDuration.len > 2 ||
context->lisk.body.rewardExtendDuration.len == 0) {
msg->result = ETH_PLUGIN_RESULT_ERROR;
}

context->next_param = LOCK_ID;
break;
case LOCK_ID:
copy_parameter(context->lisk.body.rewardExtendDuration.lock_id[counter].value,
msg->parameter,
INT256_LENGTH);
context->next_param = DURATION;
break;
case DURATION:
copy_parameter(context->lisk.body.rewardExtendDuration.duration[counter].value,
msg->parameter,
INT256_LENGTH);
if (context->lisk.body.rewardExtendDuration.len > 1 &&
counter < context->lisk.body.rewardExtendDuration.len - 1) {
counter++;
context->next_param = LOCK_ID;
} else {
context->next_param = NONE;
}
break;
case NONE:
break;
default:
PRINTF("Param not supported\n");
msg->result = ETH_PLUGIN_RESULT_ERROR;
break;
}
}

static void handle_add_unused_rewards(ethPluginProvideParameter_t *msg, context_t *context) {
switch (context->next_param) {
case AMOUNT:
copy_parameter(context->lisk.body.rewardAddUnusedRewards.amount,
msg->parameter,
sizeof(context->lisk.body.rewardAddUnusedRewards.amount));
context->next_param = DURATION;
break;
case DURATION:
copy_parameter(context->lisk.body.rewardAddUnusedRewards.duration,
msg->parameter,
sizeof(context->lisk.body.rewardAddUnusedRewards.duration));
context->next_param = DELAY;
break;
case DELAY:
copy_parameter(context->lisk.body.rewardAddUnusedRewards.delay,
msg->parameter,
sizeof(context->lisk.body.rewardAddUnusedRewards.delay));
context->next_param = UNEXPECTED_PARAMETER;
break;
case UNEXPECTED_PARAMETER:
break;
default:
PRINTF("Param not supported: %d\n", context->next_param);
Expand Down Expand Up @@ -87,6 +265,26 @@ void handle_provide_parameter(ethPluginProvideParameter_t *msg) {
case CLAIM_MULTI_SIGNATURE_ACCOUNT:
handle_claim_multisig_account(msg, context);
break;
case REWARD_CREATE_POSITION:
handle_reward_create_position(msg, context);
break;
case REWARD_INIT_FAST_UNLOCK:
case REWARD_CLAIM_REWARDS:
case REWARD_PAUSE_UNLOCKING:
case REWARD_RESUME_UNLOCKING:
case REWARD_DELETE_POSITIONS:
handle_lock_ids_array(msg, context);
break;
case REWARD_ADD_UNUSED_REWARDS:
case REWARD_FUND_STAKING_REWARDS:
handle_add_unused_rewards(msg, context);
break;
case REWARD_INC_LOCKING_AMOUNT:
handle_increase_locking_amount(msg, context);
break;
case REWARD_EXTEND_DURATION:
handle_extend_duration(msg, context);
break;
default:
PRINTF("Selector Index not supported: %d\n", context->selectorIndex);
msg->result = ETH_PLUGIN_RESULT_ERROR;
Expand Down
30 changes: 30 additions & 0 deletions src/handle_query_contract_id.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,36 @@ void handle_query_contract_id(ethQueryContractID_t *msg) {
context->selectorIndex == CLAIM_MULTI_SIGNATURE_ACCOUNT) {
strlcpy(msg->version, "Claim LSK", msg->versionLength);
msg->result = ETH_PLUGIN_RESULT_OK;
} else if (context->selectorIndex == REWARD_CREATE_POSITION) {
strlcpy(msg->version, "Stake Amount", msg->versionLength);
msg->result = ETH_PLUGIN_RESULT_OK;
} else if (context->selectorIndex == REWARD_INIT_FAST_UNLOCK) {
strlcpy(msg->version, "Fast Unlock", msg->versionLength);
msg->result = ETH_PLUGIN_RESULT_OK;
} else if (context->selectorIndex == REWARD_CLAIM_REWARDS) {
strlcpy(msg->version, "Claim Rewards", msg->versionLength);
msg->result = ETH_PLUGIN_RESULT_OK;
} else if (context->selectorIndex == REWARD_PAUSE_UNLOCKING) {
strlcpy(msg->version, "Pause Unlocking", msg->versionLength);
msg->result = ETH_PLUGIN_RESULT_OK;
} else if (context->selectorIndex == REWARD_RESUME_UNLOCKING) {
strlcpy(msg->version, "Resume Unlocking", msg->versionLength);
msg->result = ETH_PLUGIN_RESULT_OK;
} else if (context->selectorIndex == REWARD_INC_LOCKING_AMOUNT) {
strlcpy(msg->version, "Inc Locking Amount", msg->versionLength);
msg->result = ETH_PLUGIN_RESULT_OK;
} else if (context->selectorIndex == REWARD_EXTEND_DURATION) {
strlcpy(msg->version, "Extend Duration", msg->versionLength);
msg->result = ETH_PLUGIN_RESULT_OK;
} else if (context->selectorIndex == REWARD_DELETE_POSITIONS) {
strlcpy(msg->version, "Delete Positions", msg->versionLength);
msg->result = ETH_PLUGIN_RESULT_OK;
} else if (context->selectorIndex == REWARD_ADD_UNUSED_REWARDS) {
strlcpy(msg->version, "Add Unused Rewards", msg->versionLength);
msg->result = ETH_PLUGIN_RESULT_OK;
} else if (context->selectorIndex == REWARD_FUND_STAKING_REWARDS) {
strlcpy(msg->version, "Fund Staking Rewards", msg->versionLength);
msg->result = ETH_PLUGIN_RESULT_OK;
} else {
PRINTF("Selector index: %d not supported\n", context->selectorIndex);
msg->result = ETH_PLUGIN_RESULT_ERROR;
Expand Down
Loading

0 comments on commit 4976964

Please sign in to comment.