Skip to content

Commit 5d520b8

Browse files
authored
chore: release v1.6.1 (#206)
1 parent 637b277 commit 5d520b8

7 files changed

Lines changed: 142 additions & 55 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ The LiNEAR smart contracts have been audited by [BlockSec](https://www.blocksect
3636

3737
We adopt unit tests and heavily used the [`workspace-js`](https://github.com/near/workspaces-js) test framework to test the major scenarios and workflow of the LiNEAR smart contract in the [Sandbox](https://docs.near.org/docs/develop/contracts/sandbox) environment. Lint with `rustfmt` and `clippy` is also required when making changes to contract.
3838

39-
- Install node v16
39+
- Install Node.js v20
4040
- Run `npm i` to set up the environment
4141
- Run lint with `rustfmt` and `clippy`: `make lint`
4242
- Run all tests: `make test`

bin/commands/common.js

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,37 @@
1-
module.exports.networkOption = {
1+
const prompts = require('prompts');
2+
const base58 = require('bs58');
3+
const sha256 = require('sha256');
4+
5+
exports.networkOption = {
26
describe: 'network ID',
37
default: 'testnet',
48
choices: ['testnet', 'mainnet', 'localnet']
59
};
10+
11+
exports.doubleCheck = async () => {
12+
const res = await prompts({
13+
type: 'toggle',
14+
name: 'value',
15+
message: 'Confirm?',
16+
initial: true,
17+
active: 'yes',
18+
inactive: 'no'
19+
});
20+
if (!res.value) process.exit(1);
21+
}
22+
23+
exports.parseHashReturnValue = (outcome) => {
24+
const status = outcome.status;
25+
const data = status.SuccessValue;
26+
if (!data) {
27+
throw new Error('bad return value');
28+
}
29+
30+
const buff = Buffer.from(data, 'base64');
31+
return buff.toString('ascii').replaceAll('"', "");
32+
}
33+
34+
exports.getBase58CodeHash = (code) => {
35+
const hash = Buffer.from(sha256(code), 'hex');
36+
return base58.encode(hash);
37+
}

bin/commands/propose-upgrade.js

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
const base58 = require('bs58');
2-
const sha256 = require('sha256');
31
const { readFileSync, appendFileSync, existsSync } = require("fs");
42
const { NEAR, Gas } = require("near-units");
53
const { init } = require("../near");
6-
const { networkOption } = require("./common");
4+
const nearAPI = require('near-api-js');
5+
const { networkOption, doubleCheck, parseHashReturnValue, getBase58CodeHash } = require("./common");
76

87
exports.command = 'propose-upgrade <address>';
98
exports.desc = 'Propose an upgrade in DAO';
@@ -19,7 +18,7 @@ exports.builder = yargs => {
1918
default: 'res/linear.wasm'
2019
})
2120
.option('signer', {
22-
describe: 'signer account ID to call new'
21+
describe: 'signer account ID'
2322
})
2423
.option('dao', {
2524
describe: 'DAO account Id'
@@ -72,13 +71,13 @@ exports.handler = async function (argv) {
7271
console.error(`Old blob with ${lastHash} doesn't exist. The blob might have been removed. Continue?`);
7372
await doubleCheck();
7473
} else {
75-
console.log(`Remove blob with hash ${lastHash}. Are you sure?`);
74+
console.log(`Remove outdated blob with hash ${lastHash}. Are you sure?`);
7675
await doubleCheck();
7776
await signer.functionCall({
7877
contractId: dao,
7978
methodName: 'remove_blob',
8079
args: {
81-
hash,
80+
hash: lastHash,
8281
},
8382
});
8483
console.log(`Removed blob with hash ${lastHash}`);
@@ -96,15 +95,19 @@ exports.handler = async function (argv) {
9695
// store new blob
9796
console.log(`Store blob with hash ${codeHash}. Are you sure?`);
9897
await doubleCheck();
99-
const outcome = await signer.functionCall({
100-
contractId: dao,
101-
methodName: 'store_blob',
102-
args: {
103-
code,
104-
},
105-
gas: Gas.parse('100 Tgas'),
106-
attachedDeposit: deposit,
107-
});
98+
const outcome = await signer.signAndSendTransaction(
99+
{
100+
receiverId: dao,
101+
actions: [
102+
nearAPI.transactions.functionCall(
103+
'store_blob',
104+
code,
105+
Gas.parse('100 Tgas'),
106+
deposit
107+
)
108+
]
109+
}
110+
);
108111
const hash = parseHashReturnValue(outcome);
109112
console.log(`Stored blob with hash ${hash}`);
110113
}
@@ -136,19 +139,3 @@ exports.handler = async function (argv) {
136139

137140
console.log('proposed!');
138141
}
139-
140-
function parseHashReturnValue(outcome) {
141-
const status = outcome.status;
142-
const data = status.SuccessValue;
143-
if (!data) {
144-
throw new Error('bad return value');
145-
}
146-
147-
const buff = Buffer.from(data, 'base64');
148-
return buff.toString('ascii').replaceAll('"', "");
149-
}
150-
151-
function getBase58CodeHash(code) {
152-
const hash = Buffer.from(sha256(code), 'hex');
153-
return base58.encode(hash);
154-
}

bin/commands/store-dao-contract.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
const { writeFileSync } = require("fs");
2+
const { NEAR, Gas } = require("near-units");
3+
const { init } = require("../near");
4+
const nearAPI = require('near-api-js');
5+
const { networkOption, doubleCheck, parseHashReturnValue, getBase58CodeHash } = require("./common");
6+
7+
exports.command = 'store-dao-contract <dao>';
8+
exports.desc = 'Store DAO contract code from DAO factory';
9+
exports.builder = yargs => {
10+
yargs
11+
.positional('dao', {
12+
describe: 'DAO contract address to store DAO contract code',
13+
type: 'string'
14+
})
15+
.option('network', networkOption)
16+
.option('wasm', {
17+
describe: 'DAO contract wasm file path',
18+
default: 'res/sputnikdao.wasm'
19+
})
20+
.option('signer', {
21+
describe: 'signer account ID'
22+
})
23+
.option('hash', {
24+
describe: 'DAO contract code hash to store'
25+
})
26+
.demandOption(['signer', 'dao', 'hash'])
27+
}
28+
29+
exports.handler = async function (argv) {
30+
const { dao, hash, network } = argv;
31+
32+
const factory = dao.split('.').slice(1).join('.');
33+
console.log(`Fetch DAO contract code from factory ${factory} with code hash ${hash} ...`);
34+
35+
const near = await init(network);
36+
const signer = await near.account(argv.signer);
37+
const contract = await near.account(dao);
38+
39+
const code = await signer.viewFunction(factory, 'get_code', { code_hash: hash }, { parse: (code) => code });
40+
writeFileSync(argv.wasm, code);
41+
const codeHash = getBase58CodeHash(code);
42+
if(codeHash !== hash) {
43+
console.error(`The fetched code hash ${codeHash} is not the same as the provided ${hash}`);
44+
return;
45+
}
46+
47+
const deposit = (BigInt(code.length + 32) * 10n ** 19n).toString()
48+
49+
console.log(`Store DAO contract code with hash ${codeHash} to DAO ${dao}`);
50+
console.log(`- Code hash: ${codeHash}`);
51+
console.log(`- Storage cost: ${NEAR.from(deposit).toHuman()}`);
52+
console.log(`- DAO: ${dao}`);
53+
54+
const deployedCodeHash = (await contract.state()).code_hash;
55+
if (codeHash === deployedCodeHash) {
56+
console.log(
57+
"Contract's code hash is the same as the wasm file. There's no need to store the same code again.",
58+
);
59+
return;
60+
}
61+
62+
// check if the blob already exists
63+
const found = await signer.viewFunction(dao, 'has_blob', { hash: codeHash });
64+
if (found) {
65+
console.error(`The blob with ${codeHash} already exists. No need to store the same blob.`);
66+
} else {
67+
// store new blob
68+
console.log(`Store blob with hash ${codeHash}. Are you sure?`);
69+
await doubleCheck();
70+
const outcome = await signer.signAndSendTransaction(
71+
{
72+
receiverId: dao,
73+
actions: [
74+
nearAPI.transactions.functionCall(
75+
'store_blob',
76+
code,
77+
Gas.parse('100 Tgas'),
78+
deposit
79+
)
80+
]
81+
}
82+
);
83+
const hash = parseHashReturnValue(outcome);
84+
console.log(`Stored blob with hash ${hash}`);
85+
}
86+
}

contracts/linear/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "linear"
3-
version = "1.6.0"
3+
version = "1.6.1"
44
authors = ["linguists", "dongcool"]
55
edition = "2018"
66
publish = false

contracts/linear/src/upgrade.rs

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// use crate::legacy::*;
2-
use self::legacy::ContractV1_3_0;
32
use crate::*;
43

54
#[near_bindgen]
@@ -12,25 +11,8 @@ impl LiquidStakingContract {
1211
#[init(ignore_state)]
1312
#[private]
1413
pub fn migrate() -> Self {
15-
let contract: ContractV1_3_0 = env::state_read().expect("ERR_NOT_INITIALIZED");
16-
Self {
17-
owner_id: contract.owner_id,
18-
managers: contract.managers,
19-
treasury_id: contract.treasury_id,
20-
total_share_amount: contract.total_share_amount,
21-
total_staked_near_amount: contract.total_staked_near_amount,
22-
accounts: contract.accounts,
23-
paused: contract.paused,
24-
account_storage_usage: contract.account_storage_usage,
25-
beneficiaries: contract.beneficiaries,
26-
validator_pool: contract.validator_pool,
27-
whitelist_account_id: contract.whitelist_account_id,
28-
epoch_requested_stake_amount: contract.epoch_requested_stake_amount,
29-
epoch_requested_unstake_amount: contract.epoch_requested_unstake_amount,
30-
stake_amount_to_settle: contract.stake_amount_to_settle,
31-
unstake_amount_to_settle: contract.unstake_amount_to_settle,
32-
last_settlement_epoch: contract.last_settlement_epoch,
33-
}
14+
let contract: LiquidStakingContract = env::state_read().expect("ERR_NOT_INITIALIZED");
15+
contract
3416
}
3517
}
3618

0 commit comments

Comments
 (0)