00Overview
The signature validation does not enforce low-s values. For every valid `(r, s)` signature, `(r, n - s)` produces a different hash but recovers the same signer. Submitting the malleable signature as a "new" signature bypasses the `usedSignatures` replay protection and allows setting `controller` to `address(0)`.
01Retrieve ECLocker address from transaction logs
After calling deployNewLock(), find the ECLocker address under Topic 1 of the NewLock event on Etherscan.
02Compute the malleable s value
const n = BigInt("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141")
const new_s = n - BigInt(original_s)03Call changeController with malleable signature
locker.changeController(v, r, bytes32(new_s), address(0))04Open the lock as any address
locker.open(v, r, bytes32(new_s))05Level Completed

