Skip to content

Commit

Permalink
feat: Add wrapped ICX token
Browse files Browse the repository at this point in the history
  • Loading branch information
AntonAndell committed Nov 18, 2024
1 parent 5a059c6 commit 7fed623
Show file tree
Hide file tree
Showing 7 changed files with 467 additions and 0 deletions.
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;
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
}

}
Loading

0 comments on commit 7fed623

Please sign in to comment.