Skip to content

Commit

Permalink
feat: github tasks (#4)
Browse files Browse the repository at this point in the history
* github tasks

* feat(Util): string to bytes32 conversion

* feat(release): adding github actions

* fix(ci): removing bytecode publishing

* fix(dist): removing codeowners

* fix(executables): storing gateway as immutable

* feature(dist): copying the gateway interface

* fix(formatting): prettier

Co-authored-by: Kiryl Yermakou <rma4ok@gmail.com>
  • Loading branch information
Foivos and re1ro authored Aug 17, 2022
1 parent db238d7 commit c279531
Show file tree
Hide file tree
Showing 33 changed files with 750 additions and 585 deletions.
4 changes: 4 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Lines starting with '#' are comments.
# Each line is a file pattern followed by one or more owners.

* @sammy1991106 @re1ro @Foivos
25 changes: 25 additions & 0 deletions .github/workflows/conventional-commits.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Ensure Conventional Commit message

on:
pull_request:

jobs:
ensure-CC:
runs-on: ubuntu-latest

steps:
- name: semantic-pull-request
uses: amannn/action-semantic-pull-request@v3.2.6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
# Configure additional validation for the subject based on a regex.
# This example ensures the subject doesn't start with an uppercase character.
subjectPattern: ^(?![A-Z]).+$
# If `subjectPattern` is configured, you can use this property to override
# the default error message that is shown when the pattern doesn't match.
# The variables `subject` and `title` can be used within the message.
subjectPatternError: |
The subject "{subject}" found in the pull request title "{title}"
didn't match the configured pattern. Please ensure that the subject
doesn't start with an uppercase character.
30 changes: 30 additions & 0 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Linting

on:
- pull_request

jobs:
lint:
strategy:
matrix:
node-version:
- 14.x
os:
- ubuntu-latest
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2

- name: Install Node.js
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}

- name: Install Dependencies
run: npm ci

- name: Lint
run: npm run lint

- name: Flatten
run: npm run flatten
23 changes: 23 additions & 0 deletions .github/workflows/publish-to-npm.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: 'publish to npm'

on:
workflow_dispatch:
release:
types: [published]

jobs:
publish-to-npm:
name: 'Publish to NPM'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '16.x'
registry-url: 'https://registry.npmjs.org'
- run: npm install
- run: npm run build
- run: cp -r artifacts/contracts/interfaces .
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
27 changes: 27 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Testing

on:
- pull_request

jobs:
test:
strategy:
matrix:
node-version:
- 14.x
os:
- ubuntu-latest
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2

- name: Install Node.js
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}

- name: Install Dependencies
run: npm ci

- name: Test
run: npm run test
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
artifacts
cache
build
40 changes: 40 additions & 0 deletions contracts/BytesStringUtil.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

library StringToBytes32 {
error InvalidStringLength();

function toBytes32(string memory str) internal pure returns (bytes32) {
// Converting a string to bytes32 for immutable storage
bytes memory stringBytes = bytes(str);

// We can store up to 31 bytes of data as 1 byte is for encoding length
if (stringBytes.length == 0 || stringBytes.length > 31) revert InvalidStringLength();

uint256 stringNumber = uint256(bytes32(stringBytes));

// Storing string length as the last byte of the data
stringNumber |= 0xff & stringBytes.length;
return bytes32(abi.encodePacked(stringNumber));
}
}

library Bytes32ToString {
function toTrimmedString(bytes32 stringData) internal pure returns (string memory converted) {
// recovering string length as the last byte of the data
uint256 length = 0xff & uint256(stringData);

// restoring the string with the correct length
// solhint-disable-next-line no-inline-assembly
assembly {
converted := mload(0x40)
// new "memory end" including padding (the string isn't larger than 32 bytes)
mstore(0x40, add(converted, 0x40))
// store length in memory
mstore(converted, length)
// write actual data
mstore(add(converted, 0x20), stringData)
}
}
}
14 changes: 10 additions & 4 deletions contracts/executables/AxelarExecutable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@ pragma solidity ^0.8.0;
import { IAxelarGateway } from '../interfaces/IAxelarGateway.sol';
import { IAxelarExecutable } from '../interfaces/IAxelarExecutable.sol';

abstract contract AxelarExecutable is IAxelarExecutable {
function gateway() public view virtual override returns (IAxelarGateway gateway_);
contract AxelarExecutable is IAxelarExecutable {
IAxelarGateway public immutable gateway;

constructor(address gateway_) {
if (gateway_ == address(0)) revert InvalidAddress();

gateway = IAxelarGateway(gateway_);
}

function execute(
bytes32 commandId,
Expand All @@ -16,7 +22,7 @@ abstract contract AxelarExecutable is IAxelarExecutable {
) external override {
if (bytes(sourceAddress).length != 42) revert('start');
bytes32 payloadHash = keccak256(payload);
if (!gateway().validateContractCall(commandId, sourceChain, sourceAddress, payloadHash))
if (!gateway.validateContractCall(commandId, sourceChain, sourceAddress, payloadHash))
revert NotApprovedByGateway();
_execute(sourceChain, sourceAddress, payload);
}
Expand All @@ -31,7 +37,7 @@ abstract contract AxelarExecutable is IAxelarExecutable {
) external override {
bytes32 payloadHash = keccak256(payload);
if (
!gateway().validateContractCallAndMint(
!gateway.validateContractCallAndMint(
commandId,
sourceChain,
sourceAddress,
Expand Down
19 changes: 11 additions & 8 deletions contracts/executables/AxelarForecallable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ import { IAxelarGateway } from '../interfaces/IAxelarGateway.sol';
import { IERC20 } from '../interfaces/IERC20.sol';
import { IAxelarForecallable } from '../interfaces/IAxelarForecallable.sol';

abstract contract AxelarForecallable is IAxelarForecallable {
error AlreadyForecalled();
error TransferFailed();
contract AxelarForecallable is IAxelarForecallable {
IAxelarGateway public immutable gateway;

//keccak256('forecallers');
uint256 public constant FORECALLERS_SALT = 0xdb79ee324babd8834c3c1a1a2739c004fce73b812ac9f637241ff47b19e4b71f;

function gateway() public view virtual override returns (IAxelarGateway);
constructor(address gateway_) {
if (gateway_ == address(0)) revert InvalidAddress();

gateway = IAxelarGateway(gateway_);
}

function getForecaller(
string calldata sourceChain,
Expand Down Expand Up @@ -59,7 +62,7 @@ abstract contract AxelarForecallable is IAxelarForecallable {
bytes calldata payload
) external override {
bytes32 payloadHash = keccak256(payload);
if (!gateway().validateContractCall(commandId, sourceChain, sourceAddress, payloadHash))
if (!gateway.validateContractCall(commandId, sourceChain, sourceAddress, payloadHash))
revert NotApprovedByGateway();
address forecaller = getForecaller(sourceChain, sourceAddress, payload);
if (forecaller != address(0)) {
Expand Down Expand Up @@ -106,7 +109,7 @@ abstract contract AxelarForecallable is IAxelarForecallable {
uint256 amount,
address forecaller
) external override {
address token = gateway().tokenAddresses(tokenSymbol);
address token = gateway.tokenAddresses(tokenSymbol);
uint256 amountPost = amountPostFee(amount, payload);
_safeTransferFrom(token, msg.sender, amountPost);
_checkForecallWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount, forecaller);
Expand All @@ -126,7 +129,7 @@ abstract contract AxelarForecallable is IAxelarForecallable {
) external override {
bytes32 payloadHash = keccak256(payload);
if (
!gateway().validateContractCallAndMint(
!gateway.validateContractCallAndMint(
commandId,
sourceChain,
sourceAddress,
Expand All @@ -138,7 +141,7 @@ abstract contract AxelarForecallable is IAxelarForecallable {
address forecaller = getForecallerWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount);
if (forecaller != address(0)) {
_setForecallerWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount, address(0));
address token = gateway().tokenAddresses(tokenSymbol);
address token = gateway.tokenAddresses(tokenSymbol);
_safeTransfer(token, forecaller, amount);
} else {
_executeWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount);
Expand Down
3 changes: 2 additions & 1 deletion contracts/interfaces/IAxelarExecutable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ pragma solidity ^0.8.0;
import { IAxelarGateway } from '../interfaces/IAxelarGateway.sol';

interface IAxelarExecutable {
error InvalidAddress();
error NotApprovedByGateway();

function gateway() external view returns (IAxelarGateway gateway_);
function gateway() external view returns (IAxelarGateway);

function execute(
bytes32 commandId,
Expand Down
3 changes: 3 additions & 0 deletions contracts/interfaces/IAxelarForecallable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ pragma solidity ^0.8.0;
import { IAxelarExecutable } from '../interfaces/IAxelarExecutable.sol';

interface IAxelarForecallable is IAxelarExecutable {
error AlreadyForecalled();
error TransferFailed();

function forecall(
string calldata sourceChain,
string calldata sourceAddress,
Expand Down
18 changes: 11 additions & 7 deletions contracts/interfaces/IAxelarGateway.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;
pragma solidity ^0.8.9;

interface IAxelarGateway {
/**********\
Expand All @@ -22,8 +22,8 @@ interface IAxelarGateway {
error TokenContractDoesNotExist(address token);
error BurnFailed(string symbol);
error MintFailed(string symbol);
error InvalidSetDailyMintLimitsParams();
error ExceedDailyMintLimit(string symbol);
error InvalidSetMintLimitsParams();
error ExceedMintLimit(string symbol);

/**********\
|* Events *|
Expand Down Expand Up @@ -81,7 +81,7 @@ interface IAxelarGateway {
uint256 sourceEventIndex
);

event TokenDailyMintLimitUpdated(string symbol, uint256 limit);
event TokenMintLimitUpdated(string symbol, uint256 limit);

event OperatorshipTransferred(bytes newOperatorsData);

Expand Down Expand Up @@ -150,9 +150,13 @@ interface IAxelarGateway {
|* Getters *|
\***********/

function tokenDailyMintLimit(string memory symbol) external view returns (uint256);
function authModule() external view returns (address);

function tokenDailyMintAmount(string memory symbol) external view returns (uint256);
function tokenDeployer() external view returns (address);

function tokenMintLimit(string memory symbol) external view returns (uint256);

function tokenMintAmount(string memory symbol) external view returns (uint256);

function allTokensFrozen() external view returns (bool);

Expand All @@ -174,7 +178,7 @@ interface IAxelarGateway {
|* Admin Functions *|
\*******************/

function setTokenDailyMintLimits(string[] calldata symbols, uint256[] calldata limits) external;
function setTokenMintLimits(string[] calldata symbols, uint256[] calldata limits) external;

function upgrade(
address newImplementation,
Expand Down
10 changes: 1 addition & 9 deletions contracts/nft-linking/NftLinker.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,12 @@ import { IAxelarGateway } from '../interfaces/IAxelarGateway.sol';
abstract contract NftLinker is AxelarExecutable, Upgradable {
using StringToAddress for string;

address public immutable gatewayAddress;

constructor(address gatewayAddress_) {
gatewayAddress = gatewayAddress_;
}
constructor(address gatewayAddress) AxelarExecutable(gatewayAddress) {}

function contractId() external pure override returns (bytes32) {
return keccak256('nft-linker');
}

function gateway() public view override returns (IAxelarGateway) {
return IAxelarGateway(gatewayAddress);
}

function _execute(
string calldata, /*sourceChain*/
string calldata sourceAddress,
Expand Down
Loading

0 comments on commit c279531

Please sign in to comment.