Skip to content

Commit 6ce124f

Browse files
authored
Merge pull request #471 from balancednetwork/feat/stakedLP-storage-migration
feat: Update stakedLP storage with migrations
2 parents 094861e + 1d12871 commit 6ce124f

5 files changed

Lines changed: 219 additions & 45 deletions

File tree

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package network.balanced.score.core.stakedlp;
2+
3+
import foundation.icon.xcall.NetworkAddress;
4+
import score.Address;
5+
import score.BranchDB;
6+
import score.Context;
7+
import score.DictDB;
8+
9+
import java.math.BigInteger;
10+
11+
public class AddressBranchDictDB {
12+
13+
protected BranchDB<Address, DictDB<BigInteger, BigInteger>> legacyAddressDictDB;
14+
protected BranchDB<String, DictDB<BigInteger, BigInteger>> addressDictDB;
15+
protected BranchDB<Address, DictDB<BigInteger, Boolean>> migrationDB;
16+
17+
public AddressBranchDictDB(String id) {
18+
this.legacyAddressDictDB = Context.newBranchDB(id, BigInteger.class);
19+
this.addressDictDB = Context.newBranchDB(id + "_migrated", BigInteger.class);
20+
this.migrationDB = Context.newBranchDB(id + "_migration_db", Boolean.class);
21+
}
22+
23+
private BigInteger getLegacy(Address address, BigInteger key) {
24+
return legacyAddressDictDB.at(address).getOrDefault(key, BigInteger.ZERO);
25+
}
26+
27+
public Boolean isMigrated(Address address, BigInteger key) {
28+
return migrationDB.at(address).getOrDefault(key, false);
29+
}
30+
31+
public BigInteger get(NetworkAddress address, BigInteger id, boolean readonly) {
32+
BigInteger total = addressDictDB.at(address.toString()).getOrDefault(id, BigInteger.ZERO);
33+
if (address.account().startsWith("hx") || address.account().startsWith("cx")) {
34+
Address iconAddr = Address.fromString(address.account());
35+
if (!isMigrated(iconAddr, id)) {
36+
total = total.add(getLegacy(iconAddr, id));
37+
if (!readonly) {
38+
migrationDB.at(iconAddr).set(id, true);
39+
}
40+
}
41+
}
42+
43+
return total;
44+
}
45+
46+
public void set(NetworkAddress address, BigInteger id, BigInteger value) {
47+
addressDictDB.at(address.toString()).set(id, value);
48+
}
49+
50+
}

core-contracts/StakedLP/src/main/java/network/balanced/score/core/stakedlp/StakedLPImpl.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@
3535

3636
public class StakedLPImpl implements StakedLP {
3737

38-
final static AddressBranchDictDB<BigInteger, BigInteger> poolStakedDetails = new AddressBranchDictDB<>("poolStakeDetails",
39-
BigInteger.class);
38+
final static AddressBranchDictDB poolStakedDetails = new AddressBranchDictDB("poolStakeDetails");
4039

4140
private static final DictDB<BigInteger, BigInteger> totalStakedAmount = Context.newDictDB("totalStaked",
4241
BigInteger.class);
@@ -125,13 +124,13 @@ public void setRewards(Address rewards) {
125124
@External(readonly = true)
126125
public BigInteger balanceOf(Address _owner, BigInteger _id) {
127126
NetworkAddress owner = new NetworkAddress(NATIVE_NID, _owner.toString());
128-
return poolStakedDetails.at(owner).getOrDefault(_id, BigInteger.ZERO);
127+
return poolStakedDetails.get(owner, _id, true);
129128
}
130129

131130
@External(readonly = true)
132131
public BigInteger xBalanceOf(String _owner, BigInteger _id) {
133132
NetworkAddress owner = NetworkAddress.valueOf(_owner, NATIVE_NID);
134-
return poolStakedDetails.at(owner).getOrDefault(_id, BigInteger.ZERO);
133+
return poolStakedDetails.get(owner, _id, true);
135134
}
136135

137136
@External(readonly = true)
@@ -160,7 +159,8 @@ public void unstake(BigInteger id, BigInteger value) {
160159

161160
private void unstake(BigInteger id, NetworkAddress user, BigInteger value) {
162161
Context.require(value.compareTo(BigInteger.ZERO) > 0, "StakedLP: Cannot unstake less than zero value");
163-
BigInteger previousBalance = poolStakedDetails.at(user).getOrDefault(id, BigInteger.ZERO);
162+
BigInteger previousBalance = poolStakedDetails.get(user, id, false);
163+
164164
BigInteger previousTotal = totalStaked(id);
165165
String poolName = getSourceName(id);
166166

@@ -171,7 +171,7 @@ private void unstake(BigInteger id, NetworkAddress user, BigInteger value) {
171171
BigInteger newTotal = previousTotal.subtract(value);
172172
Context.require(newBalance.signum() >= 0 && newTotal.signum() >= 0, "StakedLP: New staked balance of user and" +
173173
" total amount can't be negative");
174-
poolStakedDetails.at(user).set(id, newBalance);
174+
poolStakedDetails.set(user, id, newBalance);
175175
totalStakedAmount.set(id, newTotal);
176176

177177
Unstake(user.toString(), id, value);
@@ -263,11 +263,11 @@ private void stake(NetworkAddress user, BigInteger id, BigInteger value) {
263263
"StakedLP: Cannot stake less than zero, value to stake " + value);
264264
String poolName = getSourceName(id);
265265
// Compute and store changes
266-
BigInteger previousBalance = poolStakedDetails.at(user).getOrDefault(id, BigInteger.ZERO);
266+
BigInteger previousBalance = poolStakedDetails.get(user, id, false);
267267
BigInteger previousTotal = totalStaked(id);
268268
BigInteger newBalance = previousBalance.add(value);
269269
BigInteger newTotal = previousTotal.add(value);
270-
poolStakedDetails.at(user).set(id, newBalance);
270+
poolStakedDetails.set(user, id, newBalance);
271271
totalStakedAmount.set(id, newTotal);
272272

273273
Stake(user.toString(), id, value);
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/*
2+
* Copyright (c) 2022-2022 Balanced.network.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package network.balanced.score.core.stakedlp;
18+
19+
import com.iconloop.score.test.Account;
20+
import com.iconloop.score.test.Score;
21+
import com.iconloop.score.test.ServiceManager;
22+
import com.iconloop.score.test.TestBase;
23+
24+
import foundation.icon.xcall.NetworkAddress;
25+
26+
import org.junit.jupiter.api.BeforeAll;
27+
import org.junit.jupiter.api.Test;
28+
29+
import score.Address;
30+
31+
import java.math.BigInteger;
32+
33+
import static org.junit.jupiter.api.Assertions.*;
34+
35+
public class DBTest extends TestBase {
36+
37+
private static final ServiceManager sm = getServiceManager();
38+
private static final Account owner = sm.createAccount();
39+
private static Score dummyScore;
40+
41+
public static class DummyScore extends AddressBranchDictDB {
42+
43+
public DummyScore() {
44+
super("test");
45+
}
46+
47+
public void setLegacy(Address address, BigInteger key, BigInteger value) {
48+
legacyAddressDictDB.at(address).set(key, value);
49+
}
50+
}
51+
52+
@BeforeAll
53+
public static void setup() throws Exception {
54+
dummyScore = sm.deploy(owner, DummyScore.class);
55+
}
56+
57+
@Test
58+
public void onlyLegacyValue() {
59+
// Arrange
60+
Address user = sm.createAccount().getAddress();
61+
BigInteger id = BigInteger.ONE;
62+
BigInteger value = BigInteger.TEN;
63+
dummyScore.invoke(owner, "setLegacy", user, id, value);
64+
65+
// Act
66+
BigInteger balance = (BigInteger) dummyScore.call("get", new NetworkAddress("test", user), id, true);
67+
68+
// Assert
69+
assertEquals(balance, value);
70+
}
71+
72+
@Test
73+
public void bothValues() {
74+
// Arrange
75+
Address user = sm.createAccount().getAddress();
76+
BigInteger id = BigInteger.ONE;
77+
BigInteger legacyValue = BigInteger.TEN;
78+
BigInteger value = BigInteger.TWO;
79+
dummyScore.invoke(owner, "setLegacy", user, id, legacyValue);
80+
dummyScore.invoke(owner, "set", new NetworkAddress("test", user), id, value);
81+
82+
// Act
83+
BigInteger balance = (BigInteger) dummyScore.call("get", new NetworkAddress("test", user), id, true);
84+
85+
// Assert
86+
assertEquals(balance, legacyValue.add(value));
87+
}
88+
89+
@Test
90+
public void migrateValue() {
91+
// Arrange
92+
Address user = sm.createAccount().getAddress();
93+
BigInteger id = BigInteger.ONE;
94+
BigInteger legacyValue = BigInteger.TEN;
95+
BigInteger value = BigInteger.TWO;
96+
dummyScore.invoke(owner, "setLegacy", user, id, legacyValue);
97+
dummyScore.invoke(owner, "set", new NetworkAddress("test", user), id, value);
98+
99+
// Act
100+
dummyScore.invoke(owner, "get", new NetworkAddress("test", user), id, false);
101+
102+
// Assert
103+
// In a real scenario set would be called, but for this the value is simply
104+
// marked as migrated and wont be used anymore
105+
BigInteger balance = (BigInteger) dummyScore.call("get", new NetworkAddress("test", user), id, true);
106+
assertEquals(balance, value);
107+
}
108+
109+
@Test
110+
public void migrateContractValue() {
111+
// Arrange
112+
Address user = dummyScore.getAddress();
113+
BigInteger id = BigInteger.ONE;
114+
BigInteger legacyValue = BigInteger.TEN;
115+
BigInteger value = BigInteger.TWO;
116+
dummyScore.invoke(owner, "setLegacy", user, id, legacyValue);
117+
dummyScore.invoke(owner, "set", new NetworkAddress("test", user), id, value);
118+
119+
// Act
120+
dummyScore.invoke(owner, "get", new NetworkAddress("test", user), id, false);
121+
122+
// Assert
123+
// In a real scenario set would be called, but for this the value is simply
124+
// marked as migrated and wont be used anymore
125+
BigInteger balance = (BigInteger) dummyScore.call("get", new NetworkAddress("test", user), id, true);
126+
assertEquals(balance, value);
127+
}
128+
129+
@Test
130+
public void onlyNew() {
131+
// Arrange
132+
Address user = sm.createAccount().getAddress();
133+
BigInteger id = BigInteger.ONE;
134+
BigInteger value = BigInteger.TWO;
135+
dummyScore.invoke(owner, "set", new NetworkAddress("test", user), id, value);
136+
137+
// Act
138+
BigInteger balance = (BigInteger) dummyScore.call("get", new NetworkAddress("test", user), id, true);
139+
140+
// Assert
141+
assertEquals(balance, value);
142+
}
143+
144+
@Test
145+
public void networkAddress() {
146+
// Arrange
147+
NetworkAddress user = new NetworkAddress("test", "test");
148+
BigInteger id = BigInteger.ONE;
149+
BigInteger value = BigInteger.TWO;
150+
dummyScore.invoke(owner, "set", user, id, value);
151+
152+
// Act
153+
BigInteger balance = (BigInteger) dummyScore.call("get", user, id, true);
154+
155+
// Assert
156+
assertEquals(balance, value);
157+
}
158+
159+
}

score-lib/src/main/java/network/balanced/score/lib/utils/AddressBranchDictDB.java

Lines changed: 0 additions & 35 deletions
This file was deleted.

score-lib/src/main/java/network/balanced/score/lib/utils/Versions.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
package network.balanced.score.lib.utils;
1818

1919
public class Versions {
20-
public final static String BALN = "v1.1.0";
20+
public final static String BALN = "v1.1.2";
2121
public final static String DIVIDENDS = "v1.0.0";
2222
public final static String LOANS = "v1.2.3";
2323
public final static String RESERVE = "v1.0.0";
@@ -34,7 +34,7 @@ public class Versions {
3434
public final static String GOVERNANCE = "v1.0.2";
3535
public final static String REBALANCING = "v1.0.0";
3636
public final static String ROUTER = "v1.1.8";
37-
public final static String STAKEDLP = "v1.0.8";
37+
public final static String STAKEDLP = "v1.0.9";
3838
public final static String BOOSTED_BALN = "v1.1.0";
3939
public final static String BRIBING = "v1.0.1";
4040
public final static String BALANCED_OTC = "v1.0.0";

0 commit comments

Comments
 (0)