Skip to content

Commit

Permalink
Merge pull request #10 from venture23-aleo/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
DeepakBomjan authored Sep 16, 2024
2 parents 421cce3 + d370588 commit d3d5a05
Show file tree
Hide file tree
Showing 16 changed files with 367 additions and 286 deletions.
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ coverage.json
*.cer
*.key
*.crt
keys.yaml
*venv
*.pem
.temp.*
Expand All @@ -23,4 +22,7 @@ keys.yaml
# ignore go build outputs
/attestor/chainService/chainService
/attestor/signingService/signingService
/attestor/proxy/proxy
/attestor/proxy/proxy

# ignore keys
attestor/signingService/secrets.yaml
2 changes: 1 addition & 1 deletion attestor/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ services:
dockerfile: ./signingService/Dockerfile
volumes:
- ./signingService/config.yaml:/configs/config.yaml
- ./signingService/keys.yaml:/configs/keys.yaml
- ./signingService/secrets.yaml:/configs/keys.yaml
ports:
- 8080:8080

Expand Down
1 change: 0 additions & 1 deletion attestor/signingService/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,3 @@ require (
google.golang.org/protobuf v1.32.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
)

2 changes: 2 additions & 0 deletions attestor/signingService/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/venture23-aleo/verulink/attestor/chainService v1.0.0 h1:GiNulgxmU3ld4ypyzFzvCGHeqsjO191XWjw1/pUwTr0=
github.com/venture23-aleo/verulink/attestor/chainService v1.0.0/go.mod h1:J1voy9x7jDgL+7E4aKYi2FshRn7xqI2iJy7nnaTgu+M=
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
Expand Down
7 changes: 0 additions & 7 deletions attestor/signingService/keys.yaml

This file was deleted.

29 changes: 22 additions & 7 deletions scripts/aws/DEPLOYMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The attestor service can be deployed using two method
1. MTLS certiciate/ key and CA certificate \
**For testnet/staging/demo depolyment Venture23 will proivde MTLS CA certificate, attestor certificate and attestor key.** \
https://docs.google.com/document/d/1K8-PXsaJHolj4TuOVRPLqLTRoD2-PHnh0lSE3vfpsQc/edit
**For Mainnet, use the openssl tool or any other method to generate the keys and a CSR, and submit CSR to Venture23. The signed certificate will be provided back. Example steps can be found [here](#mtls-key-and-csr-creation).**
2. Have Ethereum and Aleo wallet address and private keys ready

## Setup
Expand Down Expand Up @@ -98,7 +99,7 @@ Reference: [Creating and Attaching IAM Policy to user](https://docs.aws.amazon.c
"secretsmanager:GetSecretValue",
"secretsmanager:CreateSecret",
"secretsmanager:ListSecrets",
"secretsmanager:UpdateSecret"
"secretsmanager:UpdateSecret"
],
"Resource": "*"
},
Expand Down Expand Up @@ -140,9 +141,9 @@ Reference: [Creating and Attaching IAM Policy to user](https://docs.aws.amazon.c
```bash
cd verulink
```
3. Checkout to `staging` branch (for staging deployment , for mainnet use `main`)
3. Checkout to `main` branch
```bash
git checkout staging
git checkout main
```
4. Setup python virtual environment
```bash
Expand All @@ -153,6 +154,10 @@ Reference: [Creating and Attaching IAM Policy to user](https://docs.aws.amazon.c
source venv/bin/activate
```
6. Run the script
> **_Note_**: To work around the issue described in the **Troubleshooting** section, it is recommended to export the environment variable `OBJC_DISABLE_INITIALIZE_FORK_SAFETY`.
```
export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
```
> Deployment is on docker container
```bash
make deploy-to-aws
Expand All @@ -161,13 +166,13 @@ Reference: [Creating and Attaching IAM Policy to user](https://docs.aws.amazon.c
* AWS Region (default: `us-east-1`)
* AMI ID
* AWS Instance Type (default: `t3.medium`)
* Attestor node name (\<env>\_attestor_verulink_\<yourcompanyname> Eg. stg_attestor_verulink_demox_labs)
* AWS Secret Manager secret name for signing keys (default: `dev/verulink/attestor/signingservice`)
* Attestor node name (\<env>\_attestor_verulink_\<yourcompanyname> Eg. mainnet_attestor_verulink_v23)
* AWS Secret Manager secret name for signing keys (default: `mainnet/verulink/attestor/signingservice`)
- Ethereum private key
- Ethereum wallet address
- Aleo private key
- Aleo wallet address
* AWS Secret Manager secret name MTLS secret name (default: `dev/verulink/attestor/mtls`)
* AWS Secret Manager secret name MTLS secret name (default: `mainnet/verulink/attestor/mtls`)
- MTLS ca certificate file
- Attestor certificate file
- Attestor key file
Expand All @@ -191,7 +196,7 @@ Reference: [Creating and Attaching IAM Policy to user](https://docs.aws.amazon.c
## Troubleshooting
At times, keys may not be retrievable during installation. In such cases, we can manually attempt to fetch the keys by executing the following command:
If you haven't made any changes, the default SSH key name remains "attestor-ssh-key.pem."
If you haven't made any changes, the default SSH key name remains "`mainnet_attestor_verulink_<attestor_name>-ssh-key.pem`."
> This command checks with AWS Secret Manager if the keys can be retreived.
```bash
ansible-playbook scripts/aws/deploy.yml -i inventory.txt -u ubuntu --private-key=<ssh_key_name> --tags debug,retrieve_secret
Expand Down Expand Up @@ -242,3 +247,13 @@ or
```
export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
```

### mTLS Key and CSR Creation
1. Generate private key:
```
openssl genpkey -algorithm RSA -out attestor.key -pkeyopt rsa_keygen_bits:4096
```
2. Create csr
```
openssl req -new -key attestor.key -out attestor.csr -subj "/C=US/ST=State/L=City/O=Organization/OU=OrgUnit/CN=example.com"
```
2 changes: 1 addition & 1 deletion scripts/aws/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@
- name: Update keys in signingService config
ansible.builtin.template:
src: keys.j2
dest: "/home/{{ USER }}/{{ PROJECT_NAME }}/{{ SERVICE_NAME }}/signingService/keys.yaml"
dest: "/home/{{ USER }}/{{ PROJECT_NAME }}/{{ SERVICE_NAME }}/signingService/secrets.yaml"
mode: "0400"
vars:
secret_json_string: "{{ secret_data[secret_name] | from_json }}"
Expand Down
5 changes: 4 additions & 1 deletion solidity/contracts/main/Holding.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Own
import {Pausable} from "../common/Pausable.sol";
import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
import {Upgradeable} from "@thirdweb-dev/contracts/extension/Upgradeable.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

/// @title A contract that implements OwnableUpgradeable, ReentrancyGuardUpgradeable, Pausable, Initializable and Upgradeable Contracts for Holding token
contract Holding is OwnableUpgradeable, Pausable, ReentrancyGuardUpgradeable, Upgradeable {

using SafeERC20 for IIERC20;

/// @notice Event triggered when tokens are locked
/// @param account The address of the account whose tokens are locked
/// @param token The address of token which is locked
Expand Down Expand Up @@ -142,7 +145,7 @@ contract Holding is OwnableUpgradeable, Pausable, ReentrancyGuardUpgradeable, Up
function release(address user, address token) external virtual checkZeroAddress(token){
require(token != ETH_TOKEN, "Holding: eth token Address");
uint256 amount = _release(user, token);
require(IIERC20(token).transfer(user, amount), "Holding: erc20 release failed");
IIERC20(token).safeTransfer(user, amount);
}

/// @notice Releases ETH to a user
Expand Down
121 changes: 74 additions & 47 deletions solidity/contracts/main/tokenservice/TokenService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,20 @@ import {Holding} from "../Holding.sol";
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
import {Upgradeable} from "@thirdweb-dev/contracts/extension/Upgradeable.sol";

import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

/// @title TokenService Contract
/// @dev This contract implements OwnableUpgradeable, Pausable, TokenSupport, ReentrancyGuardUpgradeable, and Upgradeable contracts.
contract TokenService is
contract TokenService is
OwnableUpgradeable,
Pausable,
TokenSupport,
ReentrancyGuardUpgradeable,
Upgradeable
{
/// @dev immutable Address of Eth
using SafeERC20 for IIERC20;

/// @dev immutable Address of Eth
address immutable ETH_TOKEN = address(1);

/// @dev Address of the Bridge contract
Expand Down Expand Up @@ -55,25 +57,21 @@ contract TokenService is
__Pausable_init_unchained();
__ReentrancyGuard_init_unchained();
erc20Bridge = IBridge(bridge);
self = PacketLibrary.InNetworkAddress(
_chainId,
address(this)
);
self = PacketLibrary.InNetworkAddress(_chainId, address(this));
blackListService = IBlackListService(_blackListService);
_transferOwnership(_owner);
}

receive() external payable onlyOwner {
}
receive() external payable onlyOwner {}

/// @dev Authorizes an upgrade only if the caller is the owner
function _authorizeUpgrade(address) internal virtual view override {
function _authorizeUpgrade(address) internal view virtual override {
require(msg.sender == owner());
}

/// @notice Returns the type of token managed by the TokenService
/// @return string representation of the token type ("ERC20")
function tokenType() public virtual pure returns (string memory) {
function tokenType() public pure virtual returns (string memory) {
return "ERC20";
}

Expand All @@ -86,15 +84,18 @@ contract TokenService is
/// @notice Transfers ETH to the vault and locks it in the Holding contract
/// @param token Address of the ERC20 token
/// @param amount Amount of tokens to be transferred
function transferToVault(address token, uint256 amount) external virtual onlyOwner nonReentrant {
function transferToVault(
address token,
uint256 amount
) external virtual onlyOwner nonReentrant {
require(isEnabledToken(token), "TokenService: token not supported");
address vault = supportedTokens[token].vault;
require(vault != address(0), "TokenService: vault zero address");
if(token == ETH_TOKEN) {
(bool sent,) = vault.call{value: amount}("");
if (token == ETH_TOKEN) {
(bool sent, ) = payable(vault).call{value: amount}("");
require(sent, "TokenService: eth transfer failed");
}else {
require(IIERC20(token).transfer(vault, amount), "TokenService: erc20 transfer failed");
} else {
IIERC20(token).safeTransfer(vault, amount);
}
}

Expand All @@ -103,12 +104,23 @@ contract TokenService is
/// @param amount Amount of tokens or ETH to be transferred
/// @param receiver The intended receiver of the transferred tokens or ETH
/// @return packet representation of the transaction
function _packetify(address tokenAddress, uint256 amount, string memory receiver)
internal view returns (PacketLibrary.OutPacket memory packet)
{
require(!blackListService.isBlackListed(msg.sender), "TokenService: sender blacklisted");
require(isEnabledToken(tokenAddress), "TokenService: token not supported");
require(isAmountInRange(tokenAddress, amount), "TokenService: amount out of range");
function _packetify(
address tokenAddress,
uint256 amount,
string memory receiver
) internal view returns (PacketLibrary.OutPacket memory packet) {
require(
!blackListService.isBlackListed(msg.sender),
"TokenService: sender blacklisted"
);
require(
isEnabledToken(tokenAddress),
"TokenService: token not supported"
);
require(
isAmountInRange(tokenAddress, amount),
"TokenService: amount out of range"
);

packet.sourceTokenService = self;
packet.destTokenService = PacketLibrary.OutNetworkAddress(
Expand All @@ -117,61 +129,76 @@ contract TokenService is
);
packet.message = PacketLibrary.OutTokenMessage(
msg.sender,
supportedTokens[tokenAddress].destTokenAddress,
amount,
supportedTokens[tokenAddress].destTokenAddress,
amount,
receiver
);
packet.height = block.number;
}

/// @notice Transfers ETH to the destination chain via the bridge
/// @param receiver The intended receiver of the transferred ETH
function transfer(string memory receiver) external whenNotPaused virtual payable nonReentrant {
function transfer(
string memory receiver
) external payable virtual whenNotPaused nonReentrant {
require(erc20Bridge.validateAleoAddress(receiver));
erc20Bridge.sendMessage(_packetify(ETH_TOKEN, msg.value, receiver));
}

/// @notice Transfers ERC20 tokens to the destination chain via the bridge
/// @param tokenAddress Address of the ERC20 token
/// @param amount Amount of ERC20 tokens to be transferred
/// @param receiver The intended receiver of the transferred tokens
function transfer(address tokenAddress, uint256 amount, string memory receiver) external virtual whenNotPaused nonReentrant {
function transfer(
address tokenAddress,
uint256 amount,
string memory receiver
) external virtual whenNotPaused nonReentrant {
require(erc20Bridge.validateAleoAddress(receiver));
require(tokenAddress != ETH_TOKEN, "TokenService: only erc20 tokens");
require(IIERC20(tokenAddress).transferFrom(msg.sender, address(this), amount), "TokenService: token transfer failed");
IIERC20(tokenAddress).safeTransferFrom(
msg.sender,
address(this),
amount
);
erc20Bridge.sendMessage(_packetify(tokenAddress, amount, receiver));
}

/// @notice Transfers ERC20 tokens to the destination chain via the bridge
/// @param packet incoming packet containing information to withdraw
/// @param signatures arrays of signature of attestor
function withdraw(PacketLibrary.InPacket memory packet, bytes memory signatures) external virtual nonReentrant whenNotPaused {
require(packet.destTokenService.addr == address(this),"TokenService: invalid token service");

function withdraw(
PacketLibrary.InPacket memory packet,
bytes memory signatures
) external virtual nonReentrant whenNotPaused {
require(
packet.destTokenService.addr == address(this),
"TokenService: invalid token service"
);

address receiver = packet.message.receiverAddress;
address tokenAddress = packet.message.destTokenAddress;
uint256 amount = packet.message.amount;

require(isEnabledToken(tokenAddress), "TokenService: invalid token");
PacketLibrary.Vote quorum = erc20Bridge.consume(packet, signatures);

if(PacketLibrary.Vote.NAY == quorum || blackListService.isBlackListed(receiver)) {
if(tokenAddress == ETH_TOKEN) {
if (
PacketLibrary.Vote.NAY == quorum ||
blackListService.isBlackListed(receiver)
) {
if (tokenAddress == ETH_TOKEN) {
// eth lock
holding.lock{value:amount}(receiver);
}else {
require(IIERC20(tokenAddress).transfer(address(holding), amount),"TokenService: token holding failed");
holding.lock{value: amount}(receiver);
} else {
IIERC20(tokenAddress).safeTransfer(address(holding), amount);
holding.lock(receiver, tokenAddress, amount);
}
}else if(quorum == PacketLibrary.Vote.YEA){
if(tokenAddress == ETH_TOKEN) {
} else if (quorum == PacketLibrary.Vote.YEA) {
if (tokenAddress == ETH_TOKEN) {
// eth transfer
(bool sent,) = payable(receiver).call{value: amount}("");
(bool sent, ) = payable(receiver).call{value: amount}("");
require(sent, "TokenService: eth withdraw failed");
}else {
require(IIERC20(tokenAddress).transfer(receiver, amount), "TokenService: withdraw failed");
}
}else {
} else {
IIERC20(tokenAddress).safeTransfer(receiver, amount);
}
} else {
revert("TokenService: insufficient quorum");
}
}
Expand All @@ -182,4 +209,4 @@ contract TokenService is
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}
}
Loading

0 comments on commit d3d5a05

Please sign in to comment.