Skip to content

Commit

Permalink
Fee coin bounds check (#172)
Browse files Browse the repository at this point in the history
* Fee coin bounds check

* Sanity check reimbursement calc

* Cargo fmt
  • Loading branch information
connorwstein authored Mar 4, 2022
1 parent 9bfe8e5 commit 165823b
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 172 deletions.
25 changes: 25 additions & 0 deletions contracts/ocr2/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1532,6 +1532,7 @@ pub fn execute_accept_payeeship(
#[cfg(test)]
pub(crate) mod tests {
use super::*;
use crate::Decimal;
use cosmwasm_std::testing::{
mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage,
};
Expand Down Expand Up @@ -1708,4 +1709,28 @@ pub(crate) mod tests {
let execute_info = mock_info("payee2", &[]);
execute(deps.as_mut(), mock_env(), execute_info, msg).unwrap();
}

#[test]
fn test_calculate_reimbursement() {
use std::str::FromStr;
let recommended_gas_price = Decimal::from_str("0.011000").unwrap();
let juels_per_fee_coin = u128::from_str("6000000000000000000").unwrap(); // 6e18 juels in 1 luna (i.e. 6 link)

// Sanity check
let r = calculate_reimbursement(
&Billing {
recommended_gas_price_micro: recommended_gas_price,
observation_payment_gjuels: 0,
transmission_payment_gjuels: 0,
gas_base: Some(84_000),
gas_per_signature: Some(17_000),
gas_adjustment: Some(140),
},
juels_per_fee_coin,
1,
);
// juels = ((gas_per_sig*sigcount + gas_base)*gas_price_uluna/1e6)*juels_per_fee_coin
// juels = ((1 * 17000 + 84000)*1.4*0.011/1e6)*6e18 = 9332400000000000
assert_eq!(Uint128::from_str("9332400000000000").unwrap(), r);
}
}
2 changes: 1 addition & 1 deletion crates/owned/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ impl<'a> Auth<'a> {
self.0.save(deps.storage, &state)?;

Ok(Response::default().add_event(
Event::new("ownership_transfer_requested")
Event::new("ownership_transfer_accepted")
.add_attribute("from", old_owner)
.add_attribute("to", state.owner),
))
Expand Down
7 changes: 5 additions & 2 deletions pkg/terra/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,11 @@ func (c ReportCodec) BuildReport(oo []median.ParsedAttributedObservation) (types
}

// Add juels per fee coin value
jBytes := make([]byte, juelsPerFeeCoinSizeBytes)
report = append(report, juelsPerFeeCoin.FillBytes(jBytes)[:]...)
jBytes, err := ToBytes(juelsPerFeeCoin, juelsPerFeeCoinSizeBytes)
if err != nil {
return nil, err
}
report = append(report, jBytes...)
return report, nil
}

Expand Down
46 changes: 0 additions & 46 deletions pkg/terra/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ package terra

import (
"encoding/hex"
"encoding/json"
"errors"
"reflect"

"strconv"

cosmosSDK "github.com/cosmos/cosmos-sdk/types"

Expand All @@ -31,47 +26,6 @@ func HexToConfigDigest(s string, digest *types.ConfigDigest) (err error) {
return
}

// HexToArray process a hex encoded array by splitting
// currently not used, but left in case needed in the future
// `n` specifies the expected length of each element
// `output` is the expected output array
// `postprocess` allows the []byte output to be processed in any way
func HexToArray(s string, n int, output interface{}, parse func([]byte) interface{}) error {
// check to make sure hex encoded 2*n characters
if len(s)%(n*2) != 0 {
return errors.New("invalid string length")
}

// parse to bytes
var b []byte
if err := HexToByteArray(s, &b); err != nil {
return err
}

// create new array of parsed values based on `n` elements
arr := reflect.ValueOf(output) // get the array
arr = arr.Elem() // make settable
for i := 0; i < len(b); i += n {
// append values to array + use parse for type conversion
arr = reflect.Append(arr, reflect.ValueOf(parse(b[i:i+n])))
}

// writer
writer := reflect.ValueOf(output) // create output writer
writer = writer.Elem() // make settable
writer.Set(arr) // set
return nil
}

// RawMessageStringIntToInt converts a json string number to an int
func RawMessageStringIntToInt(msg json.RawMessage) (int, error) {
var temp string
if err := json.Unmarshal(msg, &temp); err != nil {
return 0, err
}
return strconv.Atoi(temp)
}

func MustAccAddress(addr string) cosmosSDK.AccAddress {
accAddr, err := cosmosSDK.AccAddressFromBech32(addr)
if err != nil {
Expand Down
123 changes: 0 additions & 123 deletions pkg/terra/utils_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package terra

import (
"encoding/json"
"strings"
"testing"

"github.com/smartcontractkit/libocr/offchainreporting2/types"
Expand Down Expand Up @@ -61,124 +59,3 @@ func TestHexToConfigDigest(t *testing.T) {
})
}
}

func TestHexToArray(t *testing.T) {
single := "7465737420636f6e66696720646967657374203332206368617273206c6f6e67"
singleStr := "test config digest 32 chars long"
multiple := []string{single, single, single, single, single, single}

t.Run("success-single", func(t *testing.T) {
var out [][]byte
err := HexToArray(single, 32, &out, func(b []byte) interface{} {
return b
})
assert.NoError(t, err)
assert.Equal(t, 1, len(out))
assert.Equal(t, singleStr, string(out[0]))
})

t.Run("success-short", func(t *testing.T) {
var out [][]byte
err := HexToArray(single, 8, &out, func(b []byte) interface{} {
return b
})
assert.NoError(t, err)
assert.Equal(t, 4, len(out))
for _, o := range out {
assert.True(t, strings.Contains(singleStr, string(o)))
}
})

t.Run("success", func(t *testing.T) {
var out [][]byte
err := HexToArray(strings.Join(multiple, ""), 32, &out, func(b []byte) interface{} {
return b
})
assert.NoError(t, err)
assert.Equal(t, len(multiple), len(out))
for _, o := range out {
assert.Equal(t, []byte(singleStr), o)
}
})

t.Run("success-string", func(t *testing.T) {
var out []string
err := HexToArray(strings.Join(multiple, ""), 32, &out, func(b []byte) interface{} {
return string(b)
})
assert.NoError(t, err)
assert.Equal(t, len(multiple), len(out))
for _, o := range out {
assert.Equal(t, singleStr, o)
}
})

t.Run("success-account", func(t *testing.T) {
var out []types.Account
err := HexToArray(strings.Join(multiple, ""), 32, &out, func(b []byte) interface{} {
return types.Account(b)
})
assert.NoError(t, err)
assert.Equal(t, len(multiple), len(out))
for _, o := range out {
assert.Equal(t, types.Account(singleStr), o)
}
})

t.Run("fail-invalid-length", func(t *testing.T) {
var out [][]byte
err := HexToArray(single[0:62], 32, &out, func(b []byte) interface{} {
return b
})
assert.EqualError(t, err, "invalid string length")
})

t.Run("fail-invalid-char", func(t *testing.T) {
var out [][]byte
err := HexToArray(single[0:63]+"t", 32, &out, func(b []byte) interface{} {
return b
})
assert.EqualError(t, err, "encoding/hex: invalid byte: U+0074 't'")
})
}

func TestRawMessageStringIntToInt(t *testing.T) {
inputs := []struct {
name string
input json.RawMessage
output int
success bool
}{
{
name: "success",
input: json.RawMessage(`"32"`),
output: 32,
success: true,
},
{
name: "fail-invalid",
input: json.RawMessage(`"3a"`),
output: 32,
success: false,
},
{
name: "fail-unmarshal",
input: json.RawMessage(`[]`),
output: 32,
success: false,
},
}

for _, i := range inputs {
t.Run(i.name, func(t *testing.T) {
num, err := RawMessageStringIntToInt(i.input)
if !i.success {
assert.Error(t, err)
return
}

assert.Equal(t, i.output, num)
assert.NoError(t, err)
})
}
}

0 comments on commit 165823b

Please sign in to comment.