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: Add wrapped ICX token #463

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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 @@ -45,6 +45,7 @@ public class Names {
public final static String BURNER = "Balanced-ICON Burner";
public final static String SAVINGS = "Balanced Savings";
public final static String TRICKLER = "Balanced Trickler";
public final static String WICX = "Wrapped ICX";

public final static String SPOKE_ASSET_MANAGER = "Balanced Spoke Asset Manager";
public final static String SPOKE_XCALL_MANAGER = "Balanced Spoke XCall Manager";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class Versions {
public final static String BURNER = "v1.0.0";
public final static String SAVINGS = "v1.0.0";
public final static String TRICKLER = "v1.0.0";
public final static String WICX = "v1.0.1";

public final static String SPOKE_ASSET_MANAGER = "v1.0.2";
public final static String SPOKE_XCALL_MANAGER = "v1.0.1";
Expand Down
3 changes: 3 additions & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ include 'test-lib'
include(':WorkerToken')
project(':WorkerToken').projectDir = file("token-contracts/WorkerToken")

include(':WICX')
project(':WICX').projectDir = file("token-contracts/WICX")

include(':Router')
project(':Router').projectDir = file("core-contracts/Router")

Expand Down
91 changes: 91 additions & 0 deletions token-contracts/WICX/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright (c) 2022-2022 Balanced.network.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import network.balanced.score.dependencies.*

plugins {
id 'java'
}

version '1.0.0'

repositories {
mavenCentral()
}

dependencies {
compileOnly Dependencies.javaeeApi
implementation project(':score-lib')

testImplementation Dependencies.javaeeUnitTest
testImplementation Dependencies.junitJupiter
testRuntimeOnly Dependencies.junitJupiterEngine
testImplementation project(':test-lib')
testImplementation Dependencies.mockitoCore
testImplementation Dependencies.mockitoInline
}

deployJar {
endpoints {
sejong {
uri = 'https://sejong.net.solidwallet.io/api/v3'
nid = 0x53
}
berlin {
uri = 'https://berlin.net.solidwallet.io/api/v3'
nid = 0x7
}
lisbon {
uri = 'https://lisbon.net.solidwallet.io/api/v3'
nid = 0x2
}
local {
uri = 'http://localhost:9082/api/v3'
nid = 0x3
}
mainnet {
uri = 'https://ctz.solidwallet.io/api/v3'
nid = 0x1
to = "cx3975b43d260fb8ec802cef6e60c2f4d07486f11d"
}
}
keystore = rootProject.hasProperty('keystoreName') ? "$keystoreName" : ''
password = rootProject.hasProperty('keystorePass') ? "$keystorePass" : ''
parameters {
arg("_governance", Addresses.mainnet.governance)
}
}

test {
useJUnitPlatform()
finalizedBy jacocoTestReport
}

jacocoTestReport {
dependsOn test
reports {
xml.required = true
csv.required = false
html.outputLocation = layout.buildDirectory.dir('jacocoHtml')
}
}
optimizedJar {
mainClassName = 'network.balanced.score.tokens.wicx.WICX'
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
* Copyright (c) 2022-2022 Balanced.network.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package network.balanced.score.tokens.wicx;

import network.balanced.score.lib.interfaces.tokens.IRC2;
import score.Address;
import score.Context;
import score.DictDB;
import score.VarDB;
import score.annotation.EventLog;
import score.annotation.External;
import score.annotation.Optional;
import score.annotation.Payable;

import java.math.BigInteger;

public class PayableIRC2Base implements IRC2 {

private final static String NAME = "name";
private final static String SYMBOL = "symbol";
private final static String DECIMALS = "decimals";
private final static String TOTAL_SUPPLY = "total_supply";
private final static String BALANCES = "balances";

static final Address ZERO_ADDRESS = new Address(new byte[Address.LENGTH]);

private final VarDB<String> name = Context.newVarDB(NAME, String.class);
private final VarDB<String> symbol = Context.newVarDB(SYMBOL, String.class);
private final VarDB<BigInteger> decimals = Context.newVarDB(DECIMALS, BigInteger.class);
private final VarDB<BigInteger> totalSupply = Context.newVarDB(TOTAL_SUPPLY, BigInteger.class);
protected final DictDB<Address, BigInteger> balances = Context.newDictDB(BALANCES, BigInteger.class);

protected PayableIRC2Base(String _tokenName, String _symbolName, @Optional BigInteger _decimals) {
if (this.name.get() == null) {
_decimals = _decimals == null ? BigInteger.valueOf(18L) : _decimals;
Context.require(_decimals.compareTo(BigInteger.ZERO) >= 0, "Decimals cannot be less than zero");

this.name.set(ensureNotEmpty(_tokenName));
this.symbol.set(ensureNotEmpty(_symbolName));
this.decimals.set(_decimals);
}
}

@EventLog(indexed = 3)
public void Transfer(Address _from, Address _to, BigInteger _value, byte[] _data) {
}

private String ensureNotEmpty(String str) {
Context.require(str != null && !str.trim().isEmpty(), "str is null or empty");
assert str != null;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

already thrown exception for str==null, assert not required I think

return str.trim();
}

@External(readonly = true)
public String name() {
return name.get();

Check warning on line 70 in token-contracts/WICX/src/main/java/network/balanced/score/tokens/wicx/PayableIRC2Base.java

View check run for this annotation

Codecov / codecov/patch

token-contracts/WICX/src/main/java/network/balanced/score/tokens/wicx/PayableIRC2Base.java#L70

Added line #L70 was not covered by tests
}

@External(readonly = true)
public String symbol() {
return symbol.get();

Check warning on line 75 in token-contracts/WICX/src/main/java/network/balanced/score/tokens/wicx/PayableIRC2Base.java

View check run for this annotation

Codecov / codecov/patch

token-contracts/WICX/src/main/java/network/balanced/score/tokens/wicx/PayableIRC2Base.java#L75

Added line #L75 was not covered by tests
}

@External(readonly = true)
public BigInteger decimals() {
return decimals.get();

Check warning on line 80 in token-contracts/WICX/src/main/java/network/balanced/score/tokens/wicx/PayableIRC2Base.java

View check run for this annotation

Codecov / codecov/patch

token-contracts/WICX/src/main/java/network/balanced/score/tokens/wicx/PayableIRC2Base.java#L80

Added line #L80 was not covered by tests
}

@External(readonly = true)
public BigInteger totalSupply() {
return totalSupply.getOrDefault(BigInteger.ZERO);
}

@External(readonly = true)
public BigInteger balanceOf(Address _owner) {
return balances.getOrDefault(_owner, BigInteger.ZERO);
}

@External
@Payable
public void transfer(Address _to, BigInteger _value, @Optional byte[] _data) {
transfer(Context.getCaller(), _to, _value, _data);
}

protected void transfer(Address _from, Address _to, BigInteger _value, byte[] _data) {
Context.require(_value.compareTo(BigInteger.ZERO) >= 0, this.name.get() + ": _value needs to be positive");
Context.require(balanceOf(_from).compareTo(_value) >= 0, this.name.get() + ": Insufficient balance");

this.balances.set(_from, balanceOf(_from).subtract(_value));
this.balances.set(_to, balanceOf(_to).add(_value));

byte[] dataBytes = (_data == null) ? "None".getBytes() : _data;
Transfer(_from, _to, _value, dataBytes);

if (_to.isContract()) {
Context.call(_to, "tokenFallback", _from, _value, dataBytes);
}
}

protected void mint(Address owner, BigInteger amount) {
Context.require(!ZERO_ADDRESS.equals(owner), this.name.get() + ": Owner address cannot be zero address");
Context.require(amount.compareTo(BigInteger.ZERO) >= 0, this.name.get() + ": Amount needs to be positive");

totalSupply.set(totalSupply().add(amount));
balances.set(owner, balanceOf(owner).add(amount));
Transfer(ZERO_ADDRESS, owner, amount, "mint".getBytes());
}

protected void burn(Address owner, BigInteger amount) {
Context.require(!ZERO_ADDRESS.equals(owner), this.name.get() + ": Owner address cannot be zero address");
Context.require(amount.compareTo(BigInteger.ZERO) >= 0, this.name.get() + ": Amount needs to be positive");
Context.require(balanceOf(owner).compareTo(amount) >= 0, this.name.get() + ": Insufficient Balance");

balances.set(owner, balanceOf(owner).subtract(amount));
totalSupply.set(totalSupply().subtract(amount));
Transfer(owner, ZERO_ADDRESS, amount, "burn".getBytes());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Copyright (c) 2022-2023 Balanced.network.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package network.balanced.score.tokens.wicx;

import network.balanced.score.lib.utils.Names;
import network.balanced.score.lib.utils.Versions;
import network.balanced.score.lib.utils.BalancedAddressManager;
import score.Address;
import score.Context;
import score.VarDB;
import score.annotation.External;
import score.annotation.Optional;
import score.annotation.Payable;

import java.math.BigInteger;

public class WICX extends PayableIRC2Base {

private static final String TOKEN_NAME = Names.WICX;
private static final String SYMBOL_NAME = "wICX";
private static final BigInteger DECIMALS = BigInteger.valueOf(18);
private static final String VERSION = "version";

private final VarDB<String> currentVersion = Context.newVarDB(VERSION, String.class);

public WICX(Address _governance) {
super(TOKEN_NAME, SYMBOL_NAME, DECIMALS);
if (BalancedAddressManager.getAddressByName(Names.GOVERNANCE) == null) {
BalancedAddressManager.setGovernance(_governance);
}
if (currentVersion.getOrDefault("").equals(Versions.WICX)) {
Context.revert("Can't Update same version of code");

Check warning on line 46 in token-contracts/WICX/src/main/java/network/balanced/score/tokens/wicx/WICX.java

View check run for this annotation

Codecov / codecov/patch

token-contracts/WICX/src/main/java/network/balanced/score/tokens/wicx/WICX.java#L46

Added line #L46 was not covered by tests
}
currentVersion.set(Versions.WICX);
}

@External(readonly = true)
public String version() {
return currentVersion.getOrDefault("");

Check warning on line 53 in token-contracts/WICX/src/main/java/network/balanced/score/tokens/wicx/WICX.java

View check run for this annotation

Codecov / codecov/patch

token-contracts/WICX/src/main/java/network/balanced/score/tokens/wicx/WICX.java#L53

Added line #L53 was not covered by tests
}

@Override
@Payable
@External
public void transfer(Address _to, BigInteger _value, @Optional byte[] _data) {
Address from = Context.getCaller();
BigInteger deposit = getICXDeposit();
if (deposit.compareTo(BigInteger.ZERO) > 0) {
mint(from, deposit);
}
super.transfer(_to, _value, _data);

if (!_to.isContract()) {
burn(_to, _value);
Context.transfer(_to, _value);
}
}

@External
public void unwrap(BigInteger amount) {
Address from = Context.getCaller();
burn(from, amount);
Context.transfer(from, amount);
}

@Payable
public void fallback() {
Address from = Context.getCaller();
BigInteger deposit = getICXDeposit();
if (deposit.compareTo(BigInteger.ZERO) > 0) {
mint(from, deposit);
}
}

BigInteger getICXDeposit() {
return getICXDeposit();

Check warning on line 90 in token-contracts/WICX/src/main/java/network/balanced/score/tokens/wicx/WICX.java

View check run for this annotation

Codecov / codecov/patch

token-contracts/WICX/src/main/java/network/balanced/score/tokens/wicx/WICX.java#L90

Added line #L90 was not covered by tests
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you want to return here Context.getValue();

}

}
Loading
Loading