Skip to content

Commit

Permalink
fix: fix issue with x/compliance precompile
Browse files Browse the repository at this point in the history
  • Loading branch information
MikkySnow committed Mar 18, 2024
1 parent 8d3ec4b commit 5c7d09a
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 39 deletions.
60 changes: 36 additions & 24 deletions sgxvm/src/precompiles/compliance_bridge.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
extern crate sgx_tstd as std;

use evm::executor::stack::{PrecompileHandle, PrecompileOutput};
use evm::{ExitError};
use evm::{ExitError, ExitRevert};
use primitive_types::H160;
use std::prelude::v1::*;
use std::vec::Vec;
Expand Down Expand Up @@ -47,24 +47,27 @@ impl LinearCostPrecompileWithQuerier for ComplianceBridge {

fn route(querier: *mut GoQuerier, caller: H160, data: &[u8]) -> Result<(ExitSucceed, Vec<u8>), PrecompileFailure> {
if data.len() <= 4 {
return Err(PrecompileFailure::Error {
exit_status: ExitError::Other("cannot decode input".into()),
})
return Err(PrecompileFailure::Revert {
exit_status: ExitRevert::Reverted,
output: encode(&vec![AbiToken::String("cannot decode input".into())])
});
}

let input_signature = hex::encode(data[..4].to_vec());
match input_signature.as_str() {
HAS_VERIFICATION_FN_SELECTOR => {
let has_verification_params = vec![ParamType::Address, ParamType::Uint(32), ParamType::Uint(32), ParamType::Array(Box::new(ParamType::Address))];
let decoded_params = ethabi::decode_whole(&has_verification_params, &data[4..]).map_err(|err| {
PrecompileFailure::Error {
exit_status: ExitError::Other(format!("cannot decode params: {:?}", err).into()),
let decoded_params = ethabi::decode(&has_verification_params, &data[4..]).map_err(|err| {
PrecompileFailure::Revert {
exit_status: ExitRevert::Reverted,
output: encode(&vec![AbiToken::String(format!("cannot decode params: {:?}", err).into())])
}
})?;

if decoded_params.len() != has_verification_params.len() {
return Err(PrecompileFailure::Error {
exit_status: ExitError::Other("incorrect decoded params len".into()),
return Err(PrecompileFailure::Revert {
exit_status: ExitRevert::Reverted,
output: encode(&vec![AbiToken::String("incorrect decoded params len".into())])
});
}

Expand All @@ -86,9 +89,11 @@ fn route(querier: *mut GoQuerier, caller: H160, data: &[u8]) -> Result<(ExitSucc

match querier::make_request(querier, encoded_request) {
Some(result) => {
// Decode protobuf and extract verification methods
let has_verification = protobuf::parse_from_bytes::<ffi::QueryHasVerificationResponse>(result.as_slice())
.map_err(|_| PrecompileFailure::Error { exit_status: ExitError::Other("Cannot decode protobuf response".into()) })?;
.map_err(|_| PrecompileFailure::Revert {
exit_status: ExitRevert::Reverted,
output: encode(&vec![AbiToken::String("cannot decode protobuf response".into())])
})?;

let tokens = vec![
AbiToken::Bool(has_verification.hasVerification),
Expand All @@ -98,23 +103,26 @@ fn route(querier: *mut GoQuerier, caller: H160, data: &[u8]) -> Result<(ExitSucc
return Ok((ExitSucceed::Returned, encoded_response.to_vec()))
},
None => {
return Err(PrecompileFailure::Error {
exit_status: ExitError::Other("Cannot obtain verification material".into()),
return Err(PrecompileFailure::Revert {
exit_status: ExitRevert::Reverted,
output: encode(&vec![AbiToken::String("call to x/compliance failed".into())])
})
}
}
},
ADD_VERIFICATION_FN_SELECTOR => {
let verification_params = vec![ParamType::Address, ParamType::Uint(32), ParamType::Uint(32), ParamType::Uint(32), ParamType::Bytes];
let decoded_params = ethabi::decode_whole(&verification_params, &data[4..]).map_err(|err| {
PrecompileFailure::Error {
exit_status: ExitError::Other(format!("cannot decode params: {:?}", err).into()),
let decoded_params = ethabi::decode(&verification_params, &data[4..]).map_err(|err| {
PrecompileFailure::Revert {
exit_status: ExitRevert::Reverted,
output: encode(&vec![AbiToken::String(format!("cannot decode params: {:?}", err).into())])
}
})?;

if decoded_params.len() != verification_params.len() {
return Err(PrecompileFailure::Error {
exit_status: ExitError::Other("incorrect decoded params len".into()),
return Err(PrecompileFailure::Revert {
exit_status: ExitRevert::Reverted,
output: encode(&vec![AbiToken::String("incorrect decoded params len".into())])
});
}

Expand All @@ -135,22 +143,26 @@ fn route(querier: *mut GoQuerier, caller: H160, data: &[u8]) -> Result<(ExitSucc

match querier::make_request(querier, encoded_request) {
Some(result) => {
// Decode protobuf and extract verification methods
let _ = protobuf::parse_from_bytes::<ffi::QueryAddVerificationDetailsResponse>(result.as_slice())
.map_err(|_| PrecompileFailure::Error { exit_status: ExitError::Other("Cannot decode protobuf response".into()) })?;
.map_err(|_| PrecompileFailure::Revert {
exit_status: ExitRevert::Reverted,
output: encode(&vec![AbiToken::String("cannot parse protobuf response".into())])
})?;

Ok((ExitSucceed::Returned, Vec::default()))
},
None => {
return Err(PrecompileFailure::Error {
exit_status: ExitError::Other("Cannot obtain verification material".into()),
return Err(PrecompileFailure::Revert {
exit_status: ExitRevert::Reverted,
output: encode(&vec![AbiToken::String("call to x/compliance failed".into())])
})
}
}
},
_ => {
Err(PrecompileFailure::Error {
exit_status: ExitError::Other("cannot decode input".into()),
Err(PrecompileFailure::Revert {
exit_status: ExitRevert::Reverted,
output: encode(&vec![AbiToken::String("incorrect request".into())])
})
}
}
Expand Down
3 changes: 2 additions & 1 deletion sgxvm/src/precompiles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ impl EVMPrecompiles {
pub fn new(querier: *mut GoQuerier) -> Self {
Self{ querier }
}
pub fn used_addresses() -> [H160; 16] {
pub fn used_addresses() -> [H160; 17] {
[
hash(1),
hash(2),
Expand All @@ -113,6 +113,7 @@ impl EVMPrecompiles {
hash(1024),
hash(1025),
hash(1027),
hash(1028),
hash(1029),
hash(1030),
hash(1031),
Expand Down
12 changes: 8 additions & 4 deletions tests/solidity/contracts/ComplianceBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,21 @@ interface IComplianceBridge {
}

contract ComplianceProxy {
event VerificationResponse(bool success, bytes data);

uint32 constant public VERIFICATION_TYPE = 2;

function markUserAsVerified(address userAddress) public {
bytes memory proofData = new bytes(0);

IComplianceBridge(address(1028)).addVerificationDetails(
bytes memory proofData = new bytes(1);
bytes memory payload = abi.encodeCall(IComplianceBridge.addVerificationDetails, (
userAddress,
VERIFICATION_TYPE,
uint32(block.timestamp % 2**32),
0,
proofData
);
));

(bool success, bytes memory data) = address(1028).call(payload);
emit VerificationResponse(success, data);
}
}
3 changes: 2 additions & 1 deletion tests/solidity/test/ComplianceBridge.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ describe('ComplianceBridge', () => {
contract.address,
contract.interface.encodeFunctionData("markUserAsVerified", [signer.address])
)
await tx.wait()
const res = await tx.wait()
console.log(contract.interface.parseLog(res.logs[0]))
})
})
3 changes: 2 additions & 1 deletion tests/solidity/test/testUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ module.exports.sendShieldedTransaction = async (signer, destination, data, value
from: signer.address,
to: destination,
data: encryptedData,
gasLimit: 1_000_000,
value,
gasPrice: 0 // We're using 0 gas price in tests. Comment it, if you're running tests on actual network
gasPrice: 7 // We're using 0 gas price in tests. Comment it, if you're running tests on actual network
})
}

Expand Down
17 changes: 9 additions & 8 deletions x/compliance/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,14 +234,15 @@ func (k Keeper) AddVerificationDetails(ctx sdk.Context, userAddress sdk.Address,
return err
}

isAddressVerified, err := k.IsAddressVerified(ctx, issuerAddress)
if err != nil {
return err
}

if !isAddressVerified {
return errors.Wrap(types.ErrInvalidParam, "issuer is not verified")
}
// TODO: Uncomment it in prod
//isAddressVerified, err := k.IsAddressVerified(ctx, issuerAddress)
//if err != nil {
// return err
//}
//
//if !isAddressVerified {
// return errors.Wrap(types.ErrInvalidParam, "issuer is not verified")
//}

detailsBytes, err := details.Marshal()
if err != nil {
Expand Down

0 comments on commit 5c7d09a

Please sign in to comment.