Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
public static final VarDB<BigInteger> bnusdVoteDefinitionFee = Context.newVarDB(DEFINITION_FEE, BigInteger.class);
public static final VarDB<BigInteger> quorum = Context.newVarDB(QUORUM, BigInteger.class);
private final VarDB<String> currentVersion = Context.newVarDB(VERSION, String.class);
public static final VarDB<Boolean> isShutdown = Context.newVarDB("IS_SHUTDOWN", Boolean.class);

public GovernanceImpl() {
if (launched.getOrDefault(null) == null) {
Expand Down Expand Up @@ -95,6 +96,23 @@
Context.call(SYSTEM_SCORE_ADDRESS, "setScoreOwner", score, newOwner);
}

@External
public void setIsShutdown(boolean _isShutdown) {
onlyOwnerOrContract();
isShutdown.set(_isShutdown);
}

@External(readonly = true)
public boolean getIsShutdown() {
return isShutdown.getOrDefault(false);

Check warning on line 107 in core-contracts/Governance/src/main/java/network/balanced/score/core/governance/GovernanceImpl.java

View check run for this annotation

Codecov / codecov/patch

core-contracts/Governance/src/main/java/network/balanced/score/core/governance/GovernanceImpl.java#L107

Added line #L107 was not covered by tests
}

protected void checkShutdownPermission() {
if (isShutdown.getOrDefault(false)) {
onlyOwnerOrContract();

Check warning on line 112 in core-contracts/Governance/src/main/java/network/balanced/score/core/governance/GovernanceImpl.java

View check run for this annotation

Codecov / codecov/patch

core-contracts/Governance/src/main/java/network/balanced/score/core/governance/GovernanceImpl.java#L112

Added line #L112 was not covered by tests
}
}

@External
public void setVoteDurationLimits(BigInteger min, BigInteger max) {
onlyOwnerOrContract();
Expand Down Expand Up @@ -167,12 +185,14 @@
@External
public void defineVote(String name, String description, BigInteger vote_start, BigInteger duration,
String forumLink, @Optional String transactions) {
checkShutdownPermission();
transactions = optionalDefault(transactions, "[]");
ProposalManager.defineVote(name, description, vote_start, duration, forumLink, transactions);
}

@External
public void cancelVote(BigInteger vote_index) {
checkShutdownPermission();
ProposalManager.cancelVote(vote_index);
}

Expand Down Expand Up @@ -201,6 +221,7 @@

@External
public void evaluateVote(BigInteger vote_index) {
checkShutdownPermission();
ProposalManager.evaluateVote(vote_index);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,26 @@ void defineVote() {
assertEquals(ProposalStatus.STATUS[ProposalStatus.ACTIVE], vote.get("status"));
}

@Test
void defineVote_isShutdown() {
// Arrange
Account account = sm.createAccount();
BigInteger day = (BigInteger) governance.call("getDay");
String name = "test";
String forumLink = "https://gov.balanced.network/";
String description = "test vote";
BigInteger voteStart = day.add(BigInteger.TWO);
BigInteger voteDuration = BigInteger.TWO;
String actions = "[]";
String expectedErrorMessage;
governance.invoke(owner, "setIsShutdown", true);

Executable whenShutdown = () -> governance.invoke(account, "defineVote", name, description, voteStart,
voteDuration, forumLink, actions);
expectErrorMessage(whenShutdown, "SenderNotScoreOwnerOrContract");

}

@Test
void cancelVote_Owner() {
// Arrange
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import com.eclipsesource.json.Json;
import com.eclipsesource.json.JsonObject;
import com.eclipsesource.json.JsonValue;

import foundation.icon.xcall.NetworkAddress;
import network.balanced.score.core.loans.collateral.CollateralDB;
import network.balanced.score.core.loans.debt.DebtDB;
import network.balanced.score.core.loans.positions.Position;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,11 @@ public static void claimInterest() {
}

accumulatedInterest.set(BigInteger.ZERO);
if (Context.call(Boolean.class, BalancedAddressManager.getGovernance(), "getIsShutdown")) {
TokenUtils.mintAssetTo(BalancedAddressManager.getFeehandler(), accumulatedAmount);
return;
}

BigInteger savingsRateAmount = savingsShare.get().multiply(accumulatedAmount).divide(POINTS);
TokenUtils.mintAssetTo(BalancedAddressManager.getSavings(), savingsRateAmount);
TokenUtils.mintAssetTo(BalancedAddressManager.getFeehandler(), accumulatedAmount.subtract(savingsRateAmount));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,36 @@ void claimInterest() {
assertRoundedEquals(expectedDebt.add(interest), debt);
}

@Test
void claimInterest_isShutdown() {
// Arrange
when(mockBalanced.governance.mock.getIsShutdown()).thenReturn(true);

Account account = sm.createAccount();
BigInteger collateral = BigInteger.valueOf(1000000).multiply(EXA);
BigInteger loan = BigInteger.valueOf(100000).multiply(EXA);
BigInteger expectedFee = calculateFee(loan);
BigInteger expectedDebt = loan.add(expectedFee);
BigInteger timePassed = BigInteger.valueOf(20000);
BigInteger savingsShare = BigInteger.valueOf(4000);
loans.invoke(mockBalanced.governance.account, "setSavingsRateShare", savingsShare);

// Act
takeLoanICX(account, "bnUSD", collateral, loan);
sm.getBlock().increase(timePassed.longValue()/2);
loans.invoke(mockBalanced.governance.account, "applyInterest");
BigInteger debt = getUserDebt(account, "sICX");
loans.invoke(account, "claimInterest");

// Assert
BigInteger expectedInterest = expectedDebt.multiply(SICX_INTEREST).multiply(timePassed.multiply(MICRO_SECONDS_IN_A_SECOND))
.divide(YEAR_IN_MICRO_SECONDS.multiply(POINTS));
BigInteger interest = debt.subtract(expectedDebt);
assertTrue(expectedInterest.compareTo(EXA) > 0);
verify(mockBalanced.bnUSD.mock).mintTo(mockBalanced.feehandler.getAddress(), interest, new byte[0]);
assertRoundedEquals(expectedDebt.add(interest), debt);
}

@Test
void permissions() {
assertOnlyCallableBy(mockBalanced.governance.getAddress(), loans, "setSavingsRateShare", BigInteger.ONE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,12 @@ public boolean distribute() {
}

private boolean mintAndAllocateBalnReward(BigInteger platformDay) {
if (Context.call(Boolean.class, BalancedAddressManager.getGovernance(), "getIsShutdown")) {
dailyVotableDistribution.set(platformDay, BigInteger.ZERO);
RewardsImpl.platformDay.set(platformDay.add(BigInteger.ONE));
return false;
}

BigInteger distribution = dailyDistribution(platformDay);
Context.call(getBaln(), "mint", distribution, new byte[0]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,26 @@ void distribute() {
defaultPlatformDist.multiply(emission).divide(EXA), new byte[0]);
}

@Test
void distribute_shutdown() {
// Act
when(mockBalanced.governance.mock.getIsShutdown()).thenReturn(true);

sm.getBlock().increase(DAY);
syncDistributions();
int day = ((BigInteger) rewardsScore.call("getDay")).intValue();

// Assert
BigInteger emission = (BigInteger) rewardsScore.call("getEmission", BigInteger.valueOf(-1));

verify(baln.mock, times(0)).transfer(bwt.getAddress(),
BigInteger.ZERO, new byte[0]);
verify(baln.mock, times(0)).transfer(daoFund.getAddress(),
BigInteger.ZERO, new byte[0]);
verify(baln.mock, times(0)).transfer(reserve.getAddress(),
BigInteger.ZERO, new byte[0]);
}

@Test
void claimRewards_updateRewardsData() {
// Arrange
Expand Down Expand Up @@ -101,6 +121,31 @@ void claimRewards_updateRewardsData() {
verifyBalnReward(account.getAddress(), expectedRewards);
}


@Test
void claimRewards_updateRewardsData_isShutdown() {
// Arrange
Account account = sm.createAccount();
BigInteger loansBalance = BigInteger.ONE.multiply(EXA);
BigInteger loansTotalSupply = BigInteger.TEN.multiply(EXA);
BigInteger swapBalance = BigInteger.TWO.multiply(EXA);
BigInteger swapTotalSupply = BigInteger.TEN.multiply(EXA);
when(mockBalanced.governance.mock.getIsShutdown()).thenReturn(true);

// Act
mockBalanceAndSupply(loans, "Loans", account.getAddress(), loansBalance, loansTotalSupply);
mockBalanceAndSupply(dex, "sICX/ICX", account.getAddress(), swapBalance, swapTotalSupply);
rewardsScore.invoke(loans.account, "updateRewardsData", "Loans", loansTotalSupply.subtract(loansBalance),
account.getAddress(), BigInteger.ZERO);
rewardsScore.invoke(dex.account, "updateRewardsData", "sICX/ICX", swapTotalSupply.subtract(swapBalance),
account.getAddress(), BigInteger.ZERO);

sm.getBlock().increase(DAY*2);

// Assert
verify(baln.mock, times(0)).transfer(any(), any(), any());
}

@Test
void claimRewards_updateBalanceAndSupply() {
// Arrange
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,13 @@ public interface Governance extends
Fallback,
Version {


@External(readonly = true)
BigInteger getDay();

@External(readonly = true)
public boolean getIsShutdown();

@External(readonly = true)
Map<String, BigInteger> getVotersCount(BigInteger vote_index);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,9 @@ public void withdrawEarly() {
BigInteger maxPenalty = value.divide(BigInteger.TWO);
BigInteger variablePenalty = balanceOf(sender, null);
BigInteger penaltyAmount = variablePenalty.min(maxPenalty);
if (Context.call(Boolean.class, BalancedAddressManager.getGovernance(), "getIsShutdown")) {
penaltyAmount = BigInteger.ZERO;
}
BigInteger returnAmount = value.subtract(penaltyAmount);

LockedBalance oldLocked = locked.newLockedBalance();
Expand All @@ -255,8 +258,10 @@ public void withdrawEarly() {
this.checkpoint(sender, oldLocked, locked);


if( penaltyAmount.compareTo(BigInteger.ZERO) > 0) {
Context.call(getBaln(), "transfer", this.penaltyAddress.get(), penaltyAmount,
"withdrawPenalty".getBytes());
}
Context.call(getBaln(), "transfer", sender, returnAmount, "withdrawEarly".getBytes());

users.remove(sender);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

@DisplayName("Statemachine Tests")
public class StateMachineTest extends AbstractBoostedBalnTest {
Expand All @@ -46,7 +47,7 @@ public class StateMachineTest extends AbstractBoostedBalnTest {
private final ArrayList<Account> accounts = new ArrayList<>();
private final long MAXIMUM_LOCK_WEEKS = 208;
private final long BLOCK_TIME = 2 * 1_000_000;

protected MockBalanced mockBalanced;
private Score bBalnScore;
private BoostedBalnImpl scoreSpy;

Expand Down Expand Up @@ -81,7 +82,7 @@ private void setupAccounts() {

@BeforeEach
public void setup() throws Exception {
MockBalanced mockBalanced = new MockBalanced(sm, owner);
mockBalanced = new MockBalanced(sm, owner);
MockBalanced.addressManagerMock.when(() -> BalancedAddressManager.getBaln()).thenReturn(tokenScore.getAddress());

bBalnScore = sm.deploy(owner, BoostedBalnImpl.class, mockBalanced.governance.getAddress(), "bBALN");
Expand Down Expand Up @@ -434,6 +435,20 @@ void unlockEarlyBeforeExpiry_belowMaxPenalty() {
tokenScore.invoke(penaltyAddress, "transfer", accounts.get(0).getAddress(), penalty, new byte[0]);
}

@DisplayName("early before the expiry, when shutdown")
@Test
void unlockEarlyBeforeExpiry_isShutdown() {
when(mockBalanced.governance.mock.getIsShutdown()).thenReturn(true);
long increasedUnlockTime = addWeeksToCurrentTimestamp(180);
increaseUnlockTime(accounts.get(0), BigInteger.valueOf(increasedUnlockTime));
bBalnScore.invoke(accounts.get(0), "withdrawEarly");

assertEquals(MINT_AMOUNT, tokenScore.call("balanceOf",
accounts.get(0).getAddress()));
votingBalances.put(accounts.get(0), new VotingBalance());

}

@DisplayName("early before the expiry, with max penalty")
@Test
void unlockEarlyBeforeExpiry_aboveMaxPenalty() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@

@External
public void tokenFallback(Address _from, BigInteger _value, byte[] _data) {
if (Context.call(Boolean.class, BalancedAddressManager.getGovernance(), "getIsShutdown")) {
return;

Check warning on line 118 in util-contracts/Trickler/src/main/java/network/balanced/score/util/trickler/TricklerImpl.java

View check run for this annotation

Codecov / codecov/patch

util-contracts/Trickler/src/main/java/network/balanced/score/util/trickler/TricklerImpl.java#L118

Added line #L118 was not covered by tests
}
Address token = Context.getCaller();
Context.require(tokensAllowList.contains(token), Names.TRICKLER + ": Can't accept this token");

Expand All @@ -125,6 +128,9 @@

@External
public void claimRewards(Address token) {
if (Context.call(Boolean.class, BalancedAddressManager.getGovernance(), "getIsShutdown")) {
return;

Check warning on line 132 in util-contracts/Trickler/src/main/java/network/balanced/score/util/trickler/TricklerImpl.java

View check run for this annotation

Codecov / codecov/patch

util-contracts/Trickler/src/main/java/network/balanced/score/util/trickler/TricklerImpl.java#L132

Added line #L132 was not covered by tests
}
Context.require(tokensAllowList.contains(token), Names.TRICKLER + ": Token is not listed");
BigInteger currentBlock = BigInteger.valueOf(Context.getBlockHeight());
BigInteger reward = getRewards(token);
Expand Down Expand Up @@ -153,6 +159,9 @@

@External(readonly = true)
public BigInteger getRewards(Address token) {
if (Context.call(Boolean.class, BalancedAddressManager.getGovernance(), "getIsShutdown")) {
return BigInteger.ZERO;

Check warning on line 163 in util-contracts/Trickler/src/main/java/network/balanced/score/util/trickler/TricklerImpl.java

View check run for this annotation

Codecov / codecov/patch

util-contracts/Trickler/src/main/java/network/balanced/score/util/trickler/TricklerImpl.java#L163

Added line #L163 was not covered by tests
}
BigInteger currentBlock = BigInteger.valueOf(Context.getBlockHeight());
BigInteger currentRate = tokenBlockRewardRate.getOrDefault(token, BigInteger.ZERO);

Expand All @@ -161,4 +170,10 @@

return reward;
}

@External
public void transfer(Address _tokenAddress, Address _targetAddress, BigInteger _amount) {
onlyOwner();
Context.call(_tokenAddress, "transfer", _targetAddress, _amount, new byte[0]);
}

Check warning on line 178 in util-contracts/Trickler/src/main/java/network/balanced/score/util/trickler/TricklerImpl.java

View check run for this annotation

Codecov / codecov/patch

util-contracts/Trickler/src/main/java/network/balanced/score/util/trickler/TricklerImpl.java#L176-L178

Added lines #L176 - L178 were not covered by tests
}
Loading